summaryrefslogtreecommitdiff
path: root/requests_cache
diff options
context:
space:
mode:
authorJordan Cook <jordan.cook@pioneer.com>2022-02-21 14:50:38 -0600
committerJordan Cook <jordan.cook@pioneer.com>2022-02-22 19:10:30 -0600
commit25f2cab5fd2468e36a718bf42dbfececa92addc9 (patch)
treed87132c816ceac3ef303f4c4cfeaf84fc49ca15d /requests_cache
parent8b2a6696a0f458ee748701f7c32a38b5c182fc0a (diff)
downloadrequests-cache-25f2cab5fd2468e36a718bf42dbfececa92addc9.tar.gz
Improve GridFS backend thread safety
Diffstat (limited to 'requests_cache')
-rw-r--r--requests_cache/backends/gridfs.py37
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()