繁体   English   中英

用龙卷风处理请求超时

[英]handling request timeouts with tornado

我在Tornado服务器中需要处理一些长请求。 我才刚刚开始了解Tornado异步代码的整个概念,似乎这将允许更多用户在处理我的长请求时与服务器进行交互,但这并不能解决我的问题,即请求超时

异步代码在服务器中异步工作,但是客户端保持同步,这意味着虽然服务器可以处理更多请求,但客户端“卡住”了等待响应,直到发生超时(我错了吗?)

问题是,如何解决浏览器超时问题? 换句话说,我正在寻找一种从客户端发出请求的方法,该方法将立即返回但在后台处理该请求。 处理完成后,应该以某种方式通知客户端。

是否有内置的机制或库? 处理这种情况的最佳方法是什么?

龙卷风的RequestHandler可以接受来自客户端的POST,将任务添加到队列中,然后响应“好,我知道了”:

q = collections.deque()

class MyHandler(RequestHandler):
    def post(self):
        # Your code determines what work the client requests:
        task_info = parse(self.request.body)
        q.append(task_info)
        self.finish(json.dumps({'ok': 1}))

客户端应该生成一个唯一的task_id,并将其包含在它发布的信息中。

如果您想要更复杂的任务队列,可以签出我的Toro项目 或更简单的方法是仅使用Tornado PeriodicCallback经常检查队列中是否有任务。

那么,如何通知客户任务已完成? 如果客户端是浏览器,则建议使用websocket连接。 这是Tornado的websocket文档 当有人访问您的页面时,某些Javascript应该会打开与服务器的websocket连接。 当访客提交任务时,JavaScript 首先会生成一个task_id,订阅有关该task_id的通知,然后将任务信息发布到服务器。 使用Javascript:

var ws = new WebSocket("ws://localhost:8888/websocket");
ws.onmessage = function (evt) {
   alert(evt.data);
};

/* Tell the server we want to know about this task */
function subscribe(task_id) {
    ws.send(JSON.stringify({task_id: task_id}));
}

这是服务器的websocket处理程序:

notifiers = set()

class TaskNotifier(websocket.WebSocketHandler):
    def open(self):
        notifiers.add(self)

    def on_message(self, message):
        # Client is asking to subscribe to notifications about
        # a certain task_id.
        parsed = json.loads(message)
        self.task_id = parsed['task_id']

    def on_close(self):
        notifiers.discard(self)

现在,只要您的代码从q提取任务并完成任务,它就会(在Python中)执行:

for n in notifiers:
    if n.task_id == task_id:
        n.write_message('task %s done' % task_id)

然后,浏览器中的Javascript客户端会检测到它正在等待的任务已完成。

请注意,客户端在将任务实际提交给服务器之前先订阅了有关任务的通知; 即使服务器非常快速地完成任务,这也可以确保不出现争用情况。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM