77
88from aws_xray_sdk .core import xray_recorder
99from botocore .client import BaseClient
10+ from cachetools import TTLCache
1011from wireup import Inject , service
1112
1213from eligibility_signposting_api .model .campaign_config import CampaignConfig , Rules
13- from eligibility_signposting_api .config .constants import TTL , RESERVED_TEST_CONSUMER_IDS
14+ from eligibility_signposting_api .config .constants import CACHE_TTL_SECONDS , RESERVED_TEST_CONSUMER_IDS
1415
1516BucketName = NewType ("BucketName" , str )
1617
1718logger = logging .getLogger (__name__ )
1819
20+ campaign_config_cache : TTLCache [str , list [CampaignConfig ]] = TTLCache (maxsize = 1 , ttl = CACHE_TTL_SECONDS )
21+
1922@service
2023class CampaignRepo :
2124 """Repository class for Campaign Rules, which we can use to calculate a person's eligibility for vaccination.
@@ -30,38 +33,29 @@ def __init__(
3033 super ().__init__ ()
3134 self .s3_client = s3_client
3235 self .bucket_name = bucket_name
33- self ._campaign_configs_cache : list [CampaignConfig ] | None = None
34- self ._cache_expiry_epoch : float = 0.0
35- self ._cache_ttl_seconds : int = int (TTL .get (os .getenv ("ENVIRONMENT" ), 0 ))
3636
3737 def get_campaign_configs (self , consumer_id : str ) -> Generator [CampaignConfig , None , None ]:
38- now = time .time ()
39- cache_enabled = self ._cache_ttl_seconds > 0
40- cache_valid = (
41- cache_enabled
42- and consumer_id not in RESERVED_TEST_CONSUMER_IDS
43- and self ._campaign_configs_cache is not None
44- and now < self ._cache_expiry_epoch
45- )
38+ bypass = consumer_id in RESERVED_TEST_CONSUMER_IDS
39+ cache_key = "all_campaigns"
40+ cached = None if bypass else campaign_config_cache .get (cache_key )
4641
4742 with xray_recorder .in_subsegment ("CampaignRepo.get_campaign_configs" ):
48- if cache_valid :
43+ if cached is not None :
4944 logger .info ("Using cached campaign configs" )
50- yield from self . _campaign_configs_cache
45+ yield from cached
5146 return
5247
5348 logger .info (
5449 "Refreshing campaign configs from S3 (consumer_id=%s, ttl_seconds=%s)" ,
5550 consumer_id ,
56- self . _cache_ttl_seconds ,
51+ CACHE_TTL_SECONDS ,
5752 )
58- campaign_configs = self ._load_campaign_configs_from_s3 ()
53+ configs = self ._load_campaign_configs_from_s3 ()
5954
60- if cache_enabled and consumer_id not in RESERVED_TEST_CONSUMER_IDS :
61- self ._campaign_configs_cache = campaign_configs
62- self ._cache_expiry_epoch = now + self ._cache_ttl_seconds
55+ if not bypass :
56+ campaign_config_cache [cache_key ] = configs
6357
64- yield from campaign_configs
58+ yield from configs
6559
6660 def _load_campaign_configs_from_s3 (self ) -> list [CampaignConfig ]:
6761 campaign_configs : list [CampaignConfig ] = []
0 commit comments