I want to use Redis's pubsub feature to implement comet, but pubsub doesn't have timeout, so if I ps.listen()
, it will block, even if client closes browser.
greenlet has timeout feature when spawn process. but I don't know how to combine them together.
flask's pseudo
@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?
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