Skip to content

Commit 57111ee

Browse files
authored
merge: #241 from ginger/ckantools-cache
2 parents 2902be4 + 4b389db commit 57111ee

3 files changed

Lines changed: 41 additions & 58 deletions

File tree

ckanext/versioned_datastore/lib/utils.py

Lines changed: 1 addition & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from collections import defaultdict
44
from typing import Dict, Iterable, List, Optional, Set, TypeVar
55

6-
from beaker.cache import CacheManager, cache_region, cache_regions
6+
from beaker.cache import cache_region
77
from ckan import plugins
88
from ckan.plugins import get_plugin, toolkit
99
from elasticsearch import Elasticsearch
@@ -343,33 +343,3 @@ def idownload_implementations() -> Iterable[U]:
343343

344344
def iqs_implementations() -> Iterable[V]:
345345
yield from plugins.PluginImplementations(IVersionedDatastoreQuerySchema)
346-
347-
348-
def clear_cached_metadata():
349-
"""
350-
Clears cached package and resource metadata, e.g. lists of public resource IDs.
351-
352-
Cached functions have to be added manually and cleared individually. This is partly
353-
so we can control exactly which functions to clear, and partly because beaker does
354-
not seem to have a way to clear an entire region.
355-
:return:
356-
"""
357-
cache_opts = cache_regions.get('vds')
358-
if cache_opts is None:
359-
# this shouldn't happen, but just in case
360-
cache_opts = {}
361-
for k, v in toolkit.config.items():
362-
if k.startswith('ckanext.versioned_datastore.cache.'):
363-
cache_opts[k.split('.')[-1]] = v
364-
# cache_managers does not usually seem to be populated so just construct a new ref
365-
cache_manager = CacheManager(**cache_opts)
366-
# manually list the cached functions to be cleared
367-
cached_functions = [get_public_resources, get_latest_resource_fields]
368-
for func in cached_functions:
369-
# each function has its own namespace that needs to be cleared
370-
try:
371-
cache = cache_manager.get_cache(func._arg_namespace)
372-
cache.clear()
373-
log.info(f'Cleared cache for {func.__name__}')
374-
except Exception as e:
375-
log.error(f'Failed to clear cache for {func.__name__}: {e}')

ckanext/versioned_datastore/plugin.py

Lines changed: 39 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2,32 +2,25 @@
22
from contextlib import suppress
33
from typing import List, Optional
44

5-
from beaker.cache import cache_regions
65
from ckan.plugins import (
76
SingletonPlugin,
87
implements,
98
interfaces,
109
toolkit,
1110
)
11+
from ckantools.cache import CacheClearError, clear_cache_region, configure_cache
1212
from ckantools.loaders import create_actions, create_auth
1313
from elasticsearch import Elasticsearch
1414
from pymongo import MongoClient
1515
from splitgill.manager import SplitgillClient
1616

1717
from ckanext.versioned_datastore import cli, helpers, routes
1818
from ckanext.versioned_datastore.interfaces import IVersionedDatastoreQuerySchema
19+
from ckanext.versioned_datastore.lib import utils
1920
from ckanext.versioned_datastore.lib.query.schema import register_schema
2021
from ckanext.versioned_datastore.lib.query.schemas.v1_0_0 import v1_0_0Schema
2122
from ckanext.versioned_datastore.lib.query.search.query import SchemaQuery
2223
from ckanext.versioned_datastore.lib.tasks import get_es_health, get_queue_length
23-
from ckanext.versioned_datastore.lib.utils import (
24-
RawResourceException,
25-
ReadOnlyResourceException,
26-
clear_cached_metadata,
27-
iqs_implementations,
28-
is_datastore_resource,
29-
ivds_implementations,
30-
)
3124
from ckanext.versioned_datastore.logic.basic import (
3225
action as basic_action,
3326
)
@@ -144,26 +137,22 @@ def configure(self, ckan_config):
144137
)
145138

146139
# register all custom query schemas
147-
for plugin in iqs_implementations():
140+
for plugin in utils.iqs_implementations():
148141
for query_version, query_schema in plugin.get_query_schemas():
149142
register_schema(query_version, query_schema)
150143

151144
# reserve any requested slugs
152145
from .lib.query.slugs.slugs import reserve_slug
153146

154-
for plugin in ivds_implementations():
147+
for plugin in utils.ivds_implementations():
155148
slugs = plugin.vds_reserve_slugs()
156149
for reserved_pretty_slug, query_parameters in slugs.items():
157150
query = SchemaQuery(**query_parameters)
158151
with suppress(Exception):
159152
reserve_slug(reserved_pretty_slug, query)
160153

161154
# configure cache
162-
options = {}
163-
for k, v in ckan_config.items():
164-
if k.startswith('ckanext.versioned_datastore.cache.'):
165-
options[k.split('.')[-1]] = v
166-
cache_regions.update({'vds': options})
155+
configure_cache(ckan_config, 'versioned_datastore', 'vds')
167156

168157
def is_sg_configured(self) -> bool:
169158
"""
@@ -214,7 +203,7 @@ def get_commands(self):
214203
# ITemplateHelpers
215204
def get_helpers(self):
216205
return {
217-
'is_datastore_resource': is_datastore_resource,
206+
'is_datastore_resource': utils.is_datastore_resource,
218207
'is_duplicate_ingestion': helpers.is_duplicate_ingestion,
219208
'get_human_duration': helpers.get_human_duration,
220209
'get_stat_icon': helpers.get_stat_icon,
@@ -230,7 +219,9 @@ def get_helpers(self):
230219
# IResourceController
231220
def before_show(self, resource_dict):
232221
# ensure datastore_active is set where it should be
233-
resource_dict['datastore_active'] = is_datastore_resource(resource_dict['id'])
222+
resource_dict['datastore_active'] = utils.is_datastore_resource(
223+
resource_dict['id']
224+
)
234225
# theoretically a resource could be datastore_active and have parsing disabled
235226
# at the same time if the database and ES have gotten out of sync, which isn't
236227
# ideal, but the fixes are more annoying than the problem itself
@@ -262,33 +253,55 @@ def before_update(self, context, current, resource):
262253
def after_update(self, context: dict, resource: dict):
263254
# use replace to overwrite the existing data (this is what users would expect)
264255
data_dict = {'resource_id': resource['id'], 'replace': True}
265-
with suppress(ReadOnlyResourceException), suppress(RawResourceException):
256+
with suppress(utils.ReadOnlyResourceException), suppress(
257+
utils.RawResourceException
258+
):
266259
toolkit.get_action('vds_data_add')(context, data_dict)
267-
clear_cached_metadata()
260+
try:
261+
clear_cache_region('versioned_datastore', utils, cache_name='vds')
262+
except CacheClearError as e:
263+
log.error(e)
268264

269265
# IResourceController
270266
def after_create(self, context: dict, resource: dict):
271267
# use replace to overwrite the existing data (this is what users would expect)
272268
data_dict = {'resource_id': resource['id'], 'replace': True}
273-
with suppress(ReadOnlyResourceException), suppress(RawResourceException):
269+
with suppress(utils.ReadOnlyResourceException), suppress(
270+
utils.RawResourceException
271+
):
274272
toolkit.get_action('vds_data_add')(context, data_dict)
275-
clear_cached_metadata()
273+
try:
274+
clear_cache_region('versioned_datastore', utils, cache_name='vds')
275+
except CacheClearError as e:
276+
log.error(e)
276277

277278
def before_delete(self, context: dict, resource: dict, resources: List[dict]):
278279
toolkit.get_action('vds_data_delete')(context, {'resource_id': resource['id']})
279280

280281
def after_delete(self, context: dict, resources: List[dict]):
281-
clear_cached_metadata()
282+
try:
283+
clear_cache_region('versioned_datastore', utils, cache_name='vds')
284+
except CacheClearError as e:
285+
log.error(e)
282286

283287
# IPackageController
284288
def after_create(self, context: dict, pkg_dict: dict):
285-
clear_cached_metadata()
289+
try:
290+
clear_cache_region('versioned_datastore', utils, cache_name='vds')
291+
except CacheClearError as e:
292+
log.error(e)
286293

287294
def after_update(self, context: dict, pkg_dict: dict):
288-
clear_cached_metadata()
295+
try:
296+
clear_cache_region('versioned_datastore', utils, cache_name='vds')
297+
except CacheClearError as e:
298+
log.error(e)
289299

290300
def after_delete(self, context: dict, pkg_dict: dict):
291-
clear_cached_metadata()
301+
try:
302+
clear_cache_region('versioned_datastore', utils, cache_name='vds')
303+
except CacheClearError as e:
304+
log.error(e)
292305

293306
# IConfigurer
294307
def update_config(self, config):

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ dependencies = [
3333
"xlrd==1.1.0",
3434
"fastavro==1.7.0",
3535
"cachetools>=4.2.4",
36-
"ckantools>=0.4.2"
36+
"ckantools>=0.5.0"
3737
]
3838

3939
[project.optional-dependencies]

0 commit comments

Comments
 (0)