Make cachedList go a bit faster

This commit is contained in:
Erik Johnston 2016-06-01 18:01:22 +01:00
parent 065e739d6e
commit 597013caa5
2 changed files with 45 additions and 19 deletions

View file

@ -32,6 +32,7 @@ import os
import functools
import inspect
import threading
import itertools
logger = logging.getLogger(__name__)
@ -43,6 +44,14 @@ CACHE_SIZE_FACTOR = float(os.environ.get("SYNAPSE_CACHE_FACTOR", 0.1))
class Cache(object):
__slots__ = (
"cache",
"max_entries",
"name",
"keylen",
"sequence",
"thread",
)
def __init__(self, name, max_entries=1000, keylen=1, lru=True, tree=False):
if lru:
@ -293,16 +302,21 @@ class CacheListDescriptor(object):
# cached is a dict arg -> deferred, where deferred results in a
# 2-tuple (`arg`, `result`)
cached = {}
results = {}
cached_defers = {}
missing = []
for arg in list_args:
key = list(keyargs)
key[self.list_pos] = arg
try:
res = cache.get(tuple(key)).observe()
res.addCallback(lambda r, arg: (arg, r), arg)
cached[arg] = res
res = cache.get(tuple(key))
if not res.called:
res = res.observe()
res.addCallback(lambda r, arg: (arg, r), arg)
cached_defers[arg] = res
else:
results[arg] = res.result
except KeyError:
missing.append(arg)
@ -340,12 +354,22 @@ class CacheListDescriptor(object):
res = observer.observe()
res.addCallback(lambda r, arg: (arg, r), arg)
cached[arg] = res
cached_defers[arg] = res
return preserve_context_over_deferred(defer.gatherResults(
cached.values(),
consumeErrors=True,
).addErrback(unwrapFirstError).addCallback(lambda res: dict(res)))
if cached_defers:
return preserve_context_over_deferred(defer.gatherResults(
cached_defers.values(),
consumeErrors=True,
).addCallback(
lambda res: {
k: v
for k, v in itertools.chain(results.items(), res)
}
)).addErrback(
unwrapFirstError
)
else:
return results
obj.__dict__[self.orig.__name__] = wrapped