Skip to content

Commit 6fed134

Browse files
authored
Merge pull request #4264 from hove-io/hot_fix_add_cache_to_ZE_for_stop_area
[Distributed/Excluded Zones] Add cache to ZE for stop area
2 parents a1f3a2c + b5c6b87 commit 6fed134

File tree

4 files changed

+45
-25
lines changed

4 files changed

+45
-25
lines changed

source/jormungandr/jormungandr/default_settings.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import os
55
import json
66
from flask_restful.inputs import boolean
7+
from datetime import timedelta
78

89
# sql queries will return an exception if the query did not succeed before `statement_timeout`
910
DEFAULT_SQLALCHEMY_ENGINE_OPTIONS = {
@@ -157,7 +158,7 @@
157158
'FETCH_S3_DATA_TIMEOUT': 24 * 60,
158159
# TIMEOUT_TRANSFER_PATH = 24Hours
159160
"TIMEOUT_TRANSFER_PATH": 24 * 60 * 60,
160-
'ASGARD_S3_DATA_TIMEOUT': 2 * 60,
161+
'ASGARD_S3_DATA_TIMEOUT': timedelta(hours=2).total_seconds(),
161162
}
162163

163164

@@ -169,7 +170,7 @@
169170
'TIMEOUT_AUTHENTICATION': 30,
170171
'TIMEOUT_PARAMS': 30,
171172
"FETCH_S3_DATA_TIMEOUT": 2 * 60,
172-
'ASGARD_S3_DATA_TIMEOUT': 1 * 60,
173+
'ASGARD_S3_DATA_TIMEOUT': timedelta(minutes=30).total_seconds(),
173174
}
174175

175176
MEMORY_CACHE_CONFIGURATION = (

source/jormungandr/jormungandr/excluded_zones_manager.py

+23-18
Original file line numberDiff line numberDiff line change
@@ -28,27 +28,34 @@
2828
# www.navitia.io
2929

3030
import boto3
31-
import pytz
3231
import shapely.iterops
3332
from dateutil import parser
3433
from botocore.client import Config
3534
import logging
3635
import json
3736
import shapely
38-
import datetime
3937
from typing import Dict
38+
from datetime import timedelta
4039

4140
from jormungandr import app, memory_cache, cache
4241
from jormungandr.resource_s3_object import ResourceS3Object
4342

43+
# local memory cache
44+
MEMORY_CACHE_ASGARD_S3_DATA_TIMEOUT = app.config[str('MEMORY_CACHE_CONFIGURATION')].get(
45+
str('ASGARD_S3_DATA_TIMEOUT'), timedelta(minutes=30).total_seconds()
46+
)
47+
# Redis cache
48+
CACHE_ASGARD_S3_DATA_TIMEOUT = app.config[str('CACHE_CONFIGURATION')].get(
49+
str('ASGARD_S3_DATA_TIMEOUT'), timedelta(hours=2).total_seconds()
50+
)
51+
4452

4553
class ExcludedZonesManager:
4654
excluded_shapes = dict() # type: Dict[str, shapely.geometry]
4755
asgard_s3_bucket_folder = "excluded_zones"
4856

4957
@staticmethod
50-
@cache.memoize(app.config[str('CACHE_CONFIGURATION')].get(str('ASGARD_S3_DATA_TIMEOUT'), 24 * 60))
51-
def get_object(resource_s3_object):
58+
def _get_object(resource_s3_object):
5259
logger = logging.getLogger(__name__)
5360
try:
5461
file_content = resource_s3_object.s3_object.get()['Body'].read().decode('utf-8')
@@ -58,7 +65,7 @@ def get_object(resource_s3_object):
5865
return {}
5966

6067
@staticmethod
61-
def is_activated(activation_period, date):
68+
def _is_activated(activation_period, date):
6269
if activation_period is None:
6370
return False
6471

@@ -70,10 +77,9 @@ def is_between(period, d):
7077
return any((is_between(period, date) for period in activation_period))
7178

7279
@classmethod
73-
@memory_cache.memoize(
74-
app.config[str('MEMORY_CACHE_CONFIGURATION')].get(str('ASGARD_S3_DATA_TIMEOUT'), 10 * 60)
75-
)
76-
def get_all_excluded_zones(cls):
80+
@memory_cache.memoize(MEMORY_CACHE_ASGARD_S3_DATA_TIMEOUT)
81+
@cache.memoize(CACHE_ASGARD_S3_DATA_TIMEOUT)
82+
def _get_all_excluded_zones(cls):
7783
bucket_name = app.config.get(str("ASGARD_S3_BUCKET"))
7884

7985
logger = logging.getLogger(__name__)
@@ -86,7 +92,7 @@ def get_all_excluded_zones(cls):
8692
if not obj.key.endswith('.json'):
8793
continue
8894
try:
89-
json_content = ExcludedZonesManager.get_object(ResourceS3Object(obj, None))
95+
json_content = ExcludedZonesManager._get_object(ResourceS3Object(obj, None))
9096
excluded_zones.append(json_content)
9197
except Exception:
9298
logger.exception("Error on fetching excluded zones: bucket: {}", bucket_name)
@@ -114,25 +120,24 @@ def get_all_excluded_zones(cls):
114120
return excluded_zones
115121

116122
@staticmethod
117-
@memory_cache.memoize(
118-
app.config[str('MEMORY_CACHE_CONFIGURATION')].get(str('ASGARD_S3_DATA_TIMEOUT'), 10 * 60)
119-
)
123+
@memory_cache.memoize(MEMORY_CACHE_ASGARD_S3_DATA_TIMEOUT)
124+
@cache.memoize(CACHE_ASGARD_S3_DATA_TIMEOUT)
120125
def get_excluded_zones(mode=None, date=None):
121126
excluded_zones = []
122-
for json_content in ExcludedZonesManager.get_all_excluded_zones():
127+
for json_content in ExcludedZonesManager._get_all_excluded_zones():
123128
if mode is not None and mode not in json_content.get("modes", []):
124129
continue
125-
if date is not None and not ExcludedZonesManager.is_activated(
130+
if date is not None and not ExcludedZonesManager._is_activated(
126131
json_content.get('activation_periods'), date
127132
):
128133
continue
129134
excluded_zones.append(json_content)
130135
return excluded_zones
131136

132137
@classmethod
133-
@memory_cache.memoize(app.config[str('CACHE_CONFIGURATION')].get(str('ASGARD_S3_DATA_TIMEOUT'), 10 * 60))
134-
def is_excluded(cls, obj, mode, timestamp):
135-
date = datetime.datetime.fromtimestamp(timestamp, tz=pytz.timezone("UTC")).date()
138+
@memory_cache.memoize(MEMORY_CACHE_ASGARD_S3_DATA_TIMEOUT)
139+
@cache.memoize(CACHE_ASGARD_S3_DATA_TIMEOUT)
140+
def is_excluded(cls, obj, mode, date):
136141
# update excluded zones
137142
excluded_zones = ExcludedZonesManager.get_excluded_zones(mode=mode, date=date)
138143
poi_ids = set((zone.get("poi") for zone in excluded_zones))

source/jormungandr/jormungandr/scenarios/helper_classes/fallback_durations.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@
4747
from jormungandr.scenarios.helper_classes.places_free_access import FreeAccessObject
4848
import functools
4949
import itertools
50+
import pytz
51+
import datetime
5052

5153
# The basic element stored in fallback_durations.
5254
# in DurationElement. can be found:
@@ -202,10 +204,12 @@ def _filter_free_access_with_excluded_zones(self, all_free_access):
202204
if self._request['_use_excluded_zones'] and all_free_access:
203205
# the mode is hardcoded to walking because we consider that we access to all free_access places
204206
# by walking
207+
timestamp = self._request['datetime']
208+
date = datetime.datetime.fromtimestamp(timestamp, tz=pytz.timezone("UTC")).date()
205209
is_excluded = functools.partial(
206210
excluded_zones_manager.ExcludedZonesManager.is_excluded,
207211
mode='walking',
208-
timestamp=self._request['datetime'],
212+
date=date,
209213
)
210214
return set(itertools.filterfalse(is_excluded, all_free_access))
211215
return all_free_access

source/jormungandr/jormungandr/tests/excluded_zones_manager_tests.py

+14-4
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ def mock_get_all_excluded_zones():
6464
@pytest.fixture(scope="function", autouse=True)
6565
def mock_http_karos(monkeypatch):
6666
monkeypatch.setattr(
67-
'jormungandr.excluded_zones_manager.ExcludedZonesManager.get_all_excluded_zones',
67+
'jormungandr.excluded_zones_manager.ExcludedZonesManager._get_all_excluded_zones',
6868
mock_get_all_excluded_zones,
6969
)
7070

@@ -92,15 +92,25 @@ def get_excluded_zones_test():
9292

9393

9494
def excluded_manager_is_excluded_test():
95+
import datetime
96+
import pytz
97+
9598
Coord = namedtuple('Coord', ['lon', 'lat'])
9699

97100
ExcludedZonesManager.excluded_shapes["poi:gare_de_lyon"] = shapely.wkt.loads(shape_str)
98101

99-
res = ExcludedZonesManager.is_excluded(Coord(1, 1), mode='walking', timestamp=1723280205)
102+
def ts_to_date(timestamp):
103+
return datetime.datetime.fromtimestamp(timestamp, tz=pytz.timezone("UTC")).date()
104+
105+
res = ExcludedZonesManager.is_excluded(Coord(1, 1), mode='walking', date=ts_to_date(1723280205))
100106
assert not res
101107

102-
res = ExcludedZonesManager.is_excluded(Coord(2.376365, 48.843402), mode='walking', timestamp=1723280205)
108+
res = ExcludedZonesManager.is_excluded(
109+
Coord(2.376365, 48.843402), mode='walking', date=ts_to_date(1723280205)
110+
)
103111
assert res
104112

105-
res = ExcludedZonesManager.is_excluded(Coord(2.376365, 48.843402), mode='walking', timestamp=1722502605)
113+
res = ExcludedZonesManager.is_excluded(
114+
Coord(2.376365, 48.843402), mode='walking', date=ts_to_date(1722502605)
115+
)
106116
assert not res

0 commit comments

Comments
 (0)