簡體   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