Proof of concept Redis PubSub.

This commit is contained in:
Luke Sneeringer
2014-09-03 13:30:33 -05:00
parent 0d5dbd189e
commit 446f29927d
2 changed files with 51 additions and 1 deletions

View File

@@ -28,3 +28,51 @@ class FifoQueue(object):
"""Retrieve a value from the left side of the queue."""
return json.loads(redis.lpop(self._queue_name))
class PubSub(object):
"""An abstraction class implemented for pubsub.
Intended to allow alteration of backend details in a single, consistent
way throughout the Tower application.
"""
def __init__(self, queue_name):
"""Instantiate a pubsub object, which is able to interact with a
Redis key as a pubsub.
Ideally this should be used with `contextmanager.closing` to ensure
well-behavedness:
from contextmanager import closing
with closing(PubSub('foobar')) as foobar:
for message in foobar.listen(wait=0.1):
<deal with message>
"""
self._queue_name = queue_name
self._ps = redis.pubsub(ignore_subscribe_messages=True)
self._ps.subscribe(queue_name)
def publish(self, message):
"""Publish a message to the given queue."""
redis.publish(self._queue_name, json.dumps(message))
def retrieve(self):
"""Retrieve a single message from the subcription channel
and return it.
"""
return self._ps.get_message()
def listen(self, wait=0.001):
"""Listen to content from the subscription channel indefinitely,
and yield messages as they are retrieved.
"""
while True:
message = self.retrieve()
if message is None:
time.sleep(max(wait, 0.001))
else:
yield json.loads(message)
def close(self):
"""Close the pubsub connection."""
self._ps.close()