Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to implement redis's pubsub timeout feature?

I want to use Redis's pubsub feature to implement comet, but pubsub doesn't have timeout, so if I use ps.listen(), it will block, even if client closes browser.

Greenlet has a timeout feature when spawn process, but I don't know how to combine them.

Flask's pseudo code:

@app.route('/')
def comet():
    rc = redis.Redis()
    ps = rc.pubsub()
    ps.subscribe('foo')
    for item in ps.listen():
        if item['type'] == 'message':
            return item['data']
    # ps.listen() will block, so how to make it timeout after 30 s?
like image 858
limboy Avatar asked Oct 24 '11 11:10

limboy


People also ask

How does Redis implement Pub Sub?

Pattern-matching subscriptions The Redis Pub/Sub implementation 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. Will receive all the messages sent to the channel news.

Is Redis Pub/Sub blocking?

Redis' pub/sub sends messages to clients subscribed (listening) on a channel. If you are not listening, you will miss the message (hence the blocking call). If you want to have it non-blocking, I recommend using a queue instead (redis is pretty good at that too).

Does Redis support pub sub?

Aside from data storage, Redis can be used as a Publisher/Subscriber platform. In this pattern, publishers can issue messages to any number of subscribers on a channel. These messages are fire-and-forget, in that if a message is published and no subscribers exists, the message evaporates and cannot be recovered.

When a message is published with the Publish command does Redis guarantee the order of messages in a single node?

1 Answer. Show activity on this post. First of all, if you are using PUBLISH, then it is blocking and returns only after messages have been delivered, so yes the order is guaranteed.


1 Answers

Because you're not threading (and I'm assuming this is intentional and in some cases wise) you must use a type of interrupt. Signals are a type of interrupt on Unix systems to allow you to return to a callback during a call that could block.

This example of a file open which will never return is in line with what you want to do. It's taken from http://docs.python.org/library/signal.html#module-signal

But a warning. Because Python uses a Global Interpreter Lock to perform OS signal handling it is subject to some stability problems. These problems should be rare normally though.

import signal, os

def handler(signum, frame):
    print 'Signal handler called with signal', signum
    raise IOError("Couldn't open device!")

# Set the signal handler and a 5-second alarm
signal.signal(signal.SIGALRM, handler)
signal.alarm(5)

# This open() may hang indefinitely
fd = os.open('/dev/ttyS0', os.O_RDWR)

signal.alarm(0)          # Disable the alarm
like image 81
Peter Moore Avatar answered Oct 12 '22 18:10

Peter Moore