77import warnings
88from datetime import datetime
99from datetime import timedelta
10+ from functools import cached_property
1011from urllib .parse import urlencode
1112
1213from django .contrib .staticfiles .storage import ManifestFilesMixin
@@ -379,10 +380,6 @@ def __init__(self, **settings):
379380 else :
380381 self .cloudfront_signer = None
381382
382- self ._ttl_cache = cachetools .cached (
383- cache = cachetools .TTLCache (maxsize = 2 , ttl = 3600 ), lock = threading .Lock ()
384- )
385-
386383 def get_cloudfront_signer (self , key_id , key ):
387384 cache_key = f"{ key_id } :{ key } "
388385 if cache_key not in self .__class__ ._signers :
@@ -451,6 +448,7 @@ def get_default_settings(self):
451448 "use_threads" : setting ("AWS_S3_USE_THREADS" , True ),
452449 "transfer_config" : setting ("AWS_S3_TRANSFER_CONFIG" , None ),
453450 "client_config" : setting ("AWS_S3_CLIENT_CONFIG" , None ),
451+ "client_ttl" : setting ("AWS_S3_CLIENT_TTL" , 3600 ),
454452 }
455453
456454 def __getstate__ (self ):
@@ -465,23 +463,27 @@ def __setstate__(self, state):
465463 def connection (self ):
466464 """
467465 Get the (cached) thread-safe boto3 s3 resource.
468-
469- This function has a 1 hour time to live cache for the boto3 resource.
470- We want to avoid storing a resource for too long to avoid their memory leak
471- ref https://github.com/boto/boto3/issues/1670.
472466 """
473467 return self ._ttl_cache (self ._create_connection )()
474468
475469 @property
476470 def unsigned_connection (self ):
477471 """
478472 Get the (cached) thread-safe boto3 s3 resource (unsigned).
473+ """
474+ return self ._ttl_cache (self ._create_connection )(unsigned = True )
479475
480- This function has a 1 hour time to live cache for the boto3 resource.
476+ @cached_property
477+ def _ttl_cache (self ):
478+ """
479+ This time to live cache is used to periodically recreate boto3 clients.
481480 We want to avoid storing a resource for too long to avoid their memory leak
482481 ref https://github.com/boto/boto3/issues/1670.
483482 """
484- return self ._ttl_cache (self ._create_connection )(unsigned = True )
483+ return cachetools .cached (
484+ cache = cachetools .TTLCache (maxsize = 2 , ttl = self .client_ttl ),
485+ lock = threading .Lock (),
486+ )
485487
486488 def _create_connection (self , * , unsigned = False ):
487489 """
0 commit comments