lock cache key during update
This commit is contained in:
parent
a026d42428
commit
75afa33a6e
3 changed files with 17 additions and 2 deletions
13
oml/cache.py
13
oml/cache.py
|
@ -1,3 +1,4 @@
|
||||||
|
from threading import Lock
|
||||||
import time
|
import time
|
||||||
|
|
||||||
class Cache(dict):
|
class Cache(dict):
|
||||||
|
@ -5,6 +6,12 @@ class Cache(dict):
|
||||||
def __init__(self, ttl=10):
|
def __init__(self, ttl=10):
|
||||||
self._ttl = ttl
|
self._ttl = ttl
|
||||||
self._added = {}
|
self._added = {}
|
||||||
|
self._lock = {}
|
||||||
|
|
||||||
|
def lock(self, key):
|
||||||
|
if key not in self._lock:
|
||||||
|
self._lock[key] = Lock()
|
||||||
|
self._lock[key].acquire()
|
||||||
|
|
||||||
def get(self, key):
|
def get(self, key):
|
||||||
now = time.time()
|
now = time.time()
|
||||||
|
@ -12,12 +19,18 @@ class Cache(dict):
|
||||||
if value < now:
|
if value < now:
|
||||||
self._added.pop(k, None)
|
self._added.pop(k, None)
|
||||||
self.pop(k, None)
|
self.pop(k, None)
|
||||||
|
self._lock.pop(k, None)
|
||||||
|
if key in self._lock:
|
||||||
|
self._lock[key].acquire()
|
||||||
return dict.get(self, key)
|
return dict.get(self, key)
|
||||||
|
|
||||||
def set(self, key, value, ttl=None):
|
def set(self, key, value, ttl=None):
|
||||||
ttl = ttl or self._ttl
|
ttl = ttl or self._ttl
|
||||||
self._added[key] = time.time() + ttl
|
self._added[key] = time.time() + ttl
|
||||||
dict.__setitem__(self, key, value)
|
dict.__setitem__(self, key, value)
|
||||||
|
q = self._lock.pop(key, None)
|
||||||
|
if q:
|
||||||
|
q.release()
|
||||||
|
|
||||||
def delete(self, key):
|
def delete(self, key):
|
||||||
if key in self._added:
|
if key in self._added:
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
import json
|
import json
|
||||||
import hashlib
|
import hashlib
|
||||||
import os
|
import os
|
||||||
import unicodedata
|
|
||||||
|
|
||||||
from sqlalchemy.orm import load_only
|
from sqlalchemy.orm import load_only
|
||||||
from sqlalchemy.sql.expression import text
|
from sqlalchemy.sql.expression import text
|
||||||
|
@ -52,11 +51,13 @@ def find(data):
|
||||||
key = 'group:' + hashlib.sha1(json.dumps(_keydata, sort_keys=True).encode('utf-8')).hexdigest()
|
key = 'group:' + hashlib.sha1(json.dumps(_keydata, sort_keys=True).encode('utf-8')).hexdigest()
|
||||||
g = state.cache.get(key)
|
g = state.cache.get(key)
|
||||||
if g is None:
|
if g is None:
|
||||||
|
state.cache.lock(key)
|
||||||
items = q['qs'].options(load_only('id'))
|
items = q['qs'].options(load_only('id'))
|
||||||
qs = models.Find.query.filter_by(key=q['group'])
|
qs = models.Find.query.filter_by(key=q['group'])
|
||||||
if items.first():
|
if items.first():
|
||||||
qs = qs.filter(models.Find.item_id.in_(items))
|
qs = qs.filter(models.Find.item_id.in_(items))
|
||||||
for f in qs.values('value', 'findvalue', 'sortvalue'):
|
values = list(qs.values('value', 'findvalue', 'sortvalue'))
|
||||||
|
for f in values:
|
||||||
value = f[0]
|
value = f[0]
|
||||||
findvalue = f[1]
|
findvalue = f[1]
|
||||||
sortvalue = f[2]
|
sortvalue = f[2]
|
||||||
|
|
|
@ -72,6 +72,7 @@ def findTitles(data):
|
||||||
key = 'title:' + hashlib.sha1(json.dumps(_keydata, sort_keys=True).encode('utf-8')).hexdigest()
|
key = 'title:' + hashlib.sha1(json.dumps(_keydata, sort_keys=True).encode('utf-8')).hexdigest()
|
||||||
titles = state.cache.get(key)
|
titles = state.cache.get(key)
|
||||||
if titles is None:
|
if titles is None:
|
||||||
|
state.cache.lock(key)
|
||||||
response['items'] = []
|
response['items'] = []
|
||||||
_titles = {}
|
_titles = {}
|
||||||
for i in q['qs']:
|
for i in q['qs']:
|
||||||
|
|
Loading…
Reference in a new issue