Подтвердить что ты не робот

Как реализовать redis pubsub таймаут?

Я хочу использовать функцию redis pubsub для реализации кометы, но у pubsub нет тайм-аута, поэтому, если я ps.listen(), он будет блокироваться, даже если клиент закрывает браузер.

greenlet имеет тайм-аут при запуске процесса. но я не знаю, как их объединить.

колба псевдо

@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?
4b9b3361

Ответ 1

Поскольку вы не потоки (и я предполагаю, что это намеренно, а в некоторых случаях и разумно), вы должны использовать тип прерывания. Сигналы - это тип прерывания в системах Unix, позволяющий вам вернуться к обратному вызову во время блокировки вызова.

Этот пример открытого файла, который никогда не будет возвращен, соответствует тому, что вы хотите сделать. Это взято из http://docs.python.org/library/signal.html#module-signal

Но предупреждение. Поскольку Python использует Global Interpreter Lock для выполнения обработки сигналов ОС, он подвержен некоторым проблемам стабильности. Однако эти проблемы должны быть редкими.

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