Skip to content

Instantly share code, notes, and snippets.

@motine
Last active October 12, 2021 03:35
Show Gist options
  • Star 16 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save motine/2628b0c6c19677ec5cde to your computer and use it in GitHub Desktop.
Save motine/2628b0c6c19677ec5cde to your computer and use it in GitHub Desktop.
Redis Pub/Sub with Python (notes for my collegue)

Redis Pub/Sub with Python

Overview:

  • Redis supports PUB/SUB
  • It supports pattern matching. Clients may subscribe to glob-style patterns in order to receive all the messages sent to channel names matching a given pattern.

Prerequisites

Assuming Fedora 23.

dnf install redis
systemctl start redis
systemctl enable redis

dnf install python
pip install redis

Test setup

One terminal with:

./listener.py

Another with

redis-cli # opens a repl, all subsequent commands should show something in the first terminal
> publish hausmeister "new_user_created 123456" # I made up the convention of the message (action)
> publish worker.control "new_job 123456"
> publish worker.registration "done 123456" # yes we can use nested queues
> publish nirvana "nobody listens" # the listener is not subscribed, hence, we should not see anything
> publish worker.control KILL # terminate `listener.py`
#!/usr/bin/env python
# inspired by: https://gist.github.com/jobliz/2596594
import redis
import threading
class Listener(threading.Thread):
def __init__(self, r):
threading.Thread.__init__(self)
self.redis = r
self.pubsub = self.redis.pubsub()
self.pubsub.subscribe(['hausmeister'])
self.pubsub.psubscribe(['worker.*'])
def work(self, item):
print item['channel'], ":", item['data']
def run(self):
for item in self.pubsub.listen():
if item['data'] == "KILL":
self.pubsub.unsubscribe()
print self, "unsubscribed and finished"
break
else:
self.work(item)
if __name__ == '__main__':
r = redis.Redis('127.0.0.1')
client = Listener(r)
client.start()
@daimajia
Copy link

When in Python3, it's better to add decode_responses=True when start redis.

r = redis.Redis('127.0.0.1', decode_responses=True)

@hosjiu1702
Copy link

@daimajia
but why?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment