Всякий раз, когда обработчики выполняются, нужно отправить сообщение в zeromq, оно остается висящим.

У меня есть nginx перед 8 экземплярами Tornado, и для некоторых запросов (обработчик комментариев) мне нужен Tornado для отправки сообщений на ZeroMQ. Я делаю это в конце обработчика (непосредственно перед отправкой ответа клиенту):

    # here is body of handler for comments 

    context = zmq.Context()
    port = "5252"
    socket = context.socket(zmq.PUSH)
    socket.bind("tcp://*:%s" % port)
    print "Running server on port: ", port
    socket.send("Commented")

    # here I flush response to client

Но это висит. Это реальный способ нажать на ZeroMQ всякий раз, когда выполняется обработчик?


person Damir    schedule 10.05.2014    source источник


Ответы (1)


Это реальный способ нажать на ZeroMQ всякий раз, когда выполняется обработчик?

Нет. Ваш код вызывает zmq.Context() каждый раз, когда вызывается обработчик запросов. Это плохо. Его следует вызывать ровно один раз — обычно в самом начале вашего процесса, возможно, в каком-то обработчике инициализации. Вы можете безопасно совместно использовать экземпляр контекста среди любого количества потоков.

То же самое с созданием и привязкой сокета — это нужно сделать один раз при запуске. Вы должны быть более осторожны с розеткой. Если все ваши обработчики (приложение, запрос и т. д.) выполняются в одном и том же потоке каждый раз, когда вызывается обработчик, вы можете использовать один и тот же сокет.

Другая проблема заключается в том, как вы «отправляете» на сокет PUSH. Как описано в http://api.zeromq.org/3-2%3azmq-socket, отправка на PUSH-сокет вполне может блокироваться в определенных ситуациях, и вы, вероятно, захотите этого избежать. Используйте zmq.Poller с флагом POLLOUT (и тайм-аутом 0), чтобы определить, будет ли блокироваться отправка. Если нет, то отправляйте сразу. Если это так, вам нужно решить, хотите ли вы просто удалить сообщение или сохранить его в своем приложении, чтобы повторить попытку позже.

person Guido Simone    schedule 12.05.2014