龙卷风一个处理程序阻塞另一个 [英] tornado one handler blocks for another

查看:19
本文介绍了龙卷风一个处理程序阻塞另一个的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用 python/tornado,我想建立一个小的蹦床"服务器,允许两个设备以 RESTish 方式相互通信.可能有非常优越/更简单的现成"方法来做到这一点.我欢迎这些建议,但我仍然觉得弄清楚如何使用龙卷风做我自己的事情会很有教育意义.

Using python/tornado I wanted to set up a little "trampoline" server that allows two devices to communicate with each other in a RESTish manner. There's probably vastly superior/simpler "off the shelf" ways to do this. I'd welcome those suggestions, but I still feel it would be educational to figure out how to do my own using tornado.

基本上,我的想法是让设备扮演服务器的角色,使用 GET 进行长轮询.客户端设备将 POST 到服务器,此时 POST 正文将作为被阻止的 GET 的响应传输.在 POST 响应之前,它会阻塞.然后服务器端对响应执行 PUT,该响应被传输到被阻止的 POST 并返回到设备.我也许我可以用 tornado.queues 做到这一点.但这似乎没有奏效.我的代码:

Basically, the idea was that I would have the device in the role of server doing a longpoll with a GET. The client device would POST to the server, at which point the POST body would be transferred as the response of the blocked GET. Before the POST responded, it would block. The server side then does a PUT with the response, which is transferred to the blocked POST and return to the device. I thought maybe I could do this with tornado.queues. But that appears to not have worked out. My code:

import tornado
import tornado.web
import tornado.httpserver
import tornado.queues

ToServerQueue = tornado.queues.Queue()
ToClientQueue = tornado.queues.Queue()

class Query(tornado.web.RequestHandler):
    def get(self):
        toServer = ToServerQueue.get()
        self.write(toServer)

    def post(self):
        toServer = self.request.body
        ToServerQueue.put(toServer)
        toClient = ToClientQueue.get()
        self.write(toClient)

    def put(self):
        ToClientQueue.put(self.request.body)
        self.write(bytes())

services = tornado.web.Application([(r'/query', Query)], debug=True)
services.listen(49009)
tornado.ioloop.IOLoop.instance().start()

不幸的是,ToServerQueue.get() 在队列有一个项目之前实际上不会阻塞,而是返回一个 tornado.concurrent.Future.这不是传递给 self.write() 调用的合法值.

Unfortunately, the ToServerQueue.get() does not actually block until the queue has an item, but rather returns a tornado.concurrent.Future. Which is not a legal value to pass to the self.write() call.

我想我的一般问题是双重的:

I guess my general question is twofold:

1) 一个 HTTP 动词调用(例如 get、put、post 等)如何阻塞,然后由另一个 HTTP 动词调用发出信号.

1) How can one HTTP verb invocation (e.g. get, put, post, etc) block and then be signaled by another HTTP verb invocation.

2) 如何将数据从一个调用共享到另一个调用?

2) How can I share data from one invocation to another?

我只涉及使用 Tornado 制作小型 REST 服务器的简单/直接用例.我想知道协程的东西是否是我需要的,但还没有找到一个好的教程/示例来帮助我看到光明,如果这确实是要走的路.

I've only really scratched the simple/straightforward use cases of making little REST servers with tornado. I wonder if the coroutine stuff is what I need, but haven't found a good tutorial/example of that to help me see the light, if that's indeed the way to go.

推荐答案

1) 一个 HTTP 动词调用(例如 get、put、post、u ne 等)如何阻塞,然后由另一个 HTTP 动词调用发出信号.

1) How can one HTTP verb invocation (e.g. get, put, post,u ne etc) block and then be signaled by another HTTP verb invocation.

2) 如何将数据从一个调用共享到另一个调用?

2) How can I share data from one invocation to another?

为每个请求创建新的 RequestHandler 对象.所以你需要一些协调员,例如队列 使用状态对象(在您的情况下,它将重新实现队列).

The new RequestHandler object is created for every request. So you need some coordinator e.g. queues or locks with state object (in your case it would be re-implementing queue).

tornado.queues 是协程的队列.Queue.get, Queue.put, Queue.join 返回需要解决"的 Future 对象 - 计划任务以成功或异常方式完成.要等到未来得到解决,你应该 yielded 它(就像在 tornado.queues).动词方法还需要用 tornado.gen 修饰.coroutine.

tornado.queues are queues for coroutines. Queue.get, Queue.put, Queue.join return Future objects, that need to be "resolved" - scheduled task done either with success or exception. To wait until future is resolved you should yielded it (just like in the doc examples of tornado.queues). The verbs method also need to be decorated with tornado.gen.coroutine.

import tornado.gen

class Query(tornado.web.RequestHandler):

    @tornado.gen.coroutine
    def get(self):
        toServer = yield ToServerQueue.get()
        self.write(toServer)

    @tornado.gen.coroutine
    def post(self):
        toServer = self.request.body
        yield ToServerQueue.put(toServer)
        toClient = yield ToClientQueue.get()
        self.write(toClient)

    @tornado.gen.coroutine
    def put(self):
        yield ToClientQueue.put(self.request.body)
        self.write(bytes())

GET 请求将持续(以非阻塞方式等待),直到队列中有可用的东西(或可以定义为 Queue.get arg 的超时)).

The GET request will last (wait in non-blocking manner) until something will be available on the queue (or timeout that can be defined as Queue.get arg).

tornado.queues.Queue 还提供了 get_nowait(还有 put_nowait),不需要被让出 - 立即返回队列中的项目或抛出异常.

tornado.queues.Queue provides also get_nowait (there is put_nowait as well) that don't have to be yielded - returns immediately item from queue or throws exception.

这篇关于龙卷风一个处理程序阻塞另一个的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆