diff options
| author | Jordan Cook <jordan.cook@pioneer.com> | 2022-02-21 14:50:38 -0600 |
|---|---|---|
| committer | Jordan Cook <jordan.cook@pioneer.com> | 2022-02-22 19:10:30 -0600 |
| commit | 25f2cab5fd2468e36a718bf42dbfececa92addc9 (patch) | |
| tree | d87132c816ceac3ef303f4c4cfeaf84fc49ca15d /requests_cache | |
| parent | 8b2a6696a0f458ee748701f7c32a38b5c182fc0a (diff) | |
| download | requests-cache-25f2cab5fd2468e36a718bf42dbfececa92addc9.tar.gz | |
Improve GridFS backend thread safety
Diffstat (limited to 'requests_cache')
| -rw-r--r-- | requests_cache/backends/gridfs.py | 37 |
1 files changed, 24 insertions, 13 deletions
diff --git a/requests_cache/backends/gridfs.py b/requests_cache/backends/gridfs.py index ca370f6..418dba6 100644 --- a/requests_cache/backends/gridfs.py +++ b/requests_cache/backends/gridfs.py @@ -11,13 +11,19 @@ API Reference :classes-only: :nosignatures: """ +from logging import getLogger +from threading import RLock + from gridfs import GridFS +from gridfs.errors import FileExists from pymongo import MongoClient from .._utils import get_valid_kwargs from .base import BaseCache, BaseStorage from .mongodb import MongoDict +logger = getLogger(__name__) + class GridFSCache(BaseCache): """GridFS cache backend. @@ -56,27 +62,32 @@ class GridFSPickleDict(BaseStorage): self.connection = connection or MongoClient(**connection_kwargs) self.db = self.connection[db_name] self.fs = GridFS(self.db) + self._lock = RLock() def __getitem__(self, key): - result = self.fs.find_one({'_id': key}) - if result is None: - raise KeyError - return self.serializer.loads(result.read()) + with self._lock: + result = self.fs.find_one({'_id': key}) + if result is None: + raise KeyError + return self.serializer.loads(result.read()) def __setitem__(self, key, item): - try: - self.__delitem__(key) - except KeyError: - pass value = self.serializer.dumps(item) encoding = None if isinstance(value, bytes) else 'utf-8' - self.fs.put(value, encoding=encoding, **{'_id': key}) + + with self._lock: + try: + self.fs.delete(key) + self.fs.put(value, encoding=encoding, **{'_id': key}) + except FileExists as e: + logger.warning(e, exc_info=True) def __delitem__(self, key): - res = self.fs.find_one({'_id': key}) - if res is None: - raise KeyError - self.fs.delete(res._id) + with self._lock: + res = self.fs.find_one({'_id': key}) + if res is None: + raise KeyError + self.fs.delete(res._id) def __len__(self): return self.db['fs.files'].estimated_document_count() |
