Skip to content

Instantly share code, notes, and snippets.

@jhgg
Created February 16, 2018 07:11
Show Gist options
  • Save jhgg/8542cec47ab63d62914ae0d9c45c1322 to your computer and use it in GitHub Desktop.
Save jhgg/8542cec47ab63d62914ae0d9c45c1322 to your computer and use it in GitHub Desktop.
from gevent.monkey import patch_all
patch_all()
import itertools
from gevent.event import AsyncResult
from gevent import spawn
from redis import StrictRedis
from werkzeug.local import LocalProxy
class Batchable(object):
_flush_greenlet = None
_scheduled = None
@classmethod
def get(cls, key):
if cls._scheduled is None:
cls._scheduled = {}
if key not in cls._scheduled:
result = AsyncResult()
cls._scheduled[key] = (result, LocalProxy(result.get))
if cls._flush_greenlet is None:
cls._flush_greenlet = spawn(cls._flush_batches)
return cls._scheduled[key][1]
@classmethod
def get_many(cls, keys):
raise NotImplementedError
@classmethod
def _flush_batches(cls):
scheduled = cls._scheduled
cls._scheduled = {}
cls._flush_greenlet = None
items = scheduled.items()
keys = [i[0] for i in items]
results = cls.get_many(keys)
for (key, val), result in itertools.izip(items, results):
if isinstance(result, AsyncResult):
result = result.get()
val[0].set(result)
_redis = StrictRedis()
class Redis(Batchable):
@classmethod
def get_many(cls, keys):
return _redis.mget(keys)
foo = Redis.get('foo')
bar = Redis.get('bar')
baz = Redis.get('baz')
print 'foo', foo
print 'bar', bar
print 'baz', baz
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment