13
13
# See the License for the specific language governing permissions and
14
14
# limitations under the License.
15
15
16
+ import time
16
17
from fnmatch import fnmatchcase
17
18
from functools import wraps
19
+ from functools32 import lru_cache
18
20
19
- from swift .common .utils import config_auto_int_value , get_logger , LRUCache
21
+ from swift .common .utils import config_auto_int_value , get_logger
20
22
21
23
from swift3 .exception import IAMException
22
24
from swift3 .response import AccessDenied
@@ -355,6 +357,30 @@ def wrapper(*args, **kwargs):
355
357
return real_check_iam_access
356
358
357
359
360
+ def tlru_cache (maxtime = 30 , maxsize = 1000 ):
361
+ """
362
+ Least-recently-used cache decorator with time-based cache invalidation.
363
+
364
+ Due to the technique used, an entry can expire before the TTL,
365
+ but never after.
366
+ """
367
+ def tlru_cache_decorator (func ):
368
+ @lru_cache (maxsize = maxsize )
369
+ def salted_func (__salt , * args , ** kwargs ):
370
+ return func (* args , ** kwargs )
371
+
372
+ @wraps (func )
373
+ def tlru_cache_wrapper (* args , ** kwargs ):
374
+ # Generate an extra argument, which will be the same for
375
+ # maxtime seconds. After maxtime seconds, the argument changes,
376
+ # and thus triggers a cache miss.
377
+ return salted_func (int (time .time () / maxtime ), * args , ** kwargs )
378
+
379
+ return tlru_cache_wrapper
380
+
381
+ return tlru_cache_decorator
382
+
383
+
358
384
class IamMiddleware (object ):
359
385
"""
360
386
Base class for IAM implementations.
@@ -368,8 +394,13 @@ def __init__(self, app, conf):
368
394
self .connection = conf .get ('connection' )
369
395
maxsize = config_auto_int_value (conf .get ('cache_size' ), 1000 )
370
396
maxtime = config_auto_int_value (conf .get ('cache_ttl' ), 30 )
371
- self ._load_rules_matcher = LRUCache (maxsize = maxsize , maxtime = maxtime )(
372
- self ._build_rules_matcher )
397
+ if maxsize > 0 :
398
+ if maxtime <= 0 :
399
+ maxtime = float ('inf' )
400
+ self ._load_rules_matcher = tlru_cache (
401
+ maxsize = maxsize , maxtime = maxtime )(self ._build_rules_matcher )
402
+ else :
403
+ self ._load_rules_matcher = self ._build_rules_matcher
373
404
374
405
def __call__ (self , env , start_response ):
375
406
# Put the rules callback in the request environment so middlewares
0 commit comments