2015-09-10 45 views
0

Tornado主IOLoop需要20s來處理新的請求我有一些繁重的計算需要在接收請求時完成而不阻塞主IOLoop。爲了實現這一目標,我使用ProcessPoolExecutor一個協程:雖然ProcessPoolExecutor

from concurrent.futures import ProcessPoolExecutor 
from functools import partial 
from random import uniform 
import uuid 
import time 
from datetime import datetime 
import tornado.ioloop 
import tornado.web 
import tornado.httpserver 

def worker_function(msg): 
     start = time.time() 
     count = 0 
     seed = 1 
     while count < 99999999: 
       seed = uniform(1.1,1.2) 
       count += 1 
     end = time.time() 
     msg['seed'] = seed 
     msg['local_time'] = end - start 
     return msg 

class EventHandler(tornado.web.RequestHandler): 

     def initialize(self): 
       self.executor = ProcessPoolExecutor(2) 

     @tornado.gen.coroutine 
     def get(self): 
       print "Received request at %s" % datetime.now() 
       result = yield self.executor.submit(
         worker_function, {'id':str(uuid.uuid1())} 
       ) 
       self.write(result) 
       self.finish() 
       print "Finished processing at %s" % datetime.now() 


if __name__ == "__main__": 
     counter = {'count':0} 
     application = tornado.web.Application([ 
       (r"/test", EventHandler), 
     ]) 
     application.listen(8888) 
     tornado.ioloop.IOLoop.instance().start() 

爲了測試正確的行爲,我加載在兩個單獨的瀏覽器選項卡中的URL在1秒左右的延遲。下面是該腳本輸出:

Received request at 2015-09-09 23:58:00.899278 
Received request at 2015-09-09 23:58:23.329648 
Finished processing at 2015-09-09 23:58:44.530322 
Finished processing at 2015-09-09 23:59:05.120466 

兩個過程確實是並行運行的,我可以看到在100%被用在HTOP兩個CPU核心。問題是兩個「接收到的請求」之間的20秒延遲。

如何確保主IOLoop保持活潑狀態?

Ps:該腳本在具有2個CPU內核的Linux VM上運行。

+0

您使用的是什麼版本的Python? –

+0

@ ThijsvanDien我正在使用python 2.7.6。 –

+0

請注意,如果我從啓動一些requests.get()調用的python腳本查詢url,問題似乎不會發生。我只能在我的瀏覽器中重現這一點。 –

回答

0

主要問題是您正在使用瀏覽器進行測試,並且瀏覽器不希望同時請求兩次相同的URL,即使它位於兩個不同的選項卡中(它們等待第一個請求完成之前從第二個開始看看他們是否得到可緩存的響應)。爲每個網址添加一個唯一的查詢參數,您應該可以看到兩個選項卡並行進行(或者在同一個瀏覽器中使用兩個不同的瀏覽器而不是兩個選項卡進行測試)。

此外,您的ProcessPoolExecutor應該是全局(或您的應用程序的成員)而不是您的RequestHandler的成員。所有請求應共享相同的執行程序。

+0

確實chrome是這裏的問題,它可以在兩個瀏覽器或一個線程化的python腳本中正常工作。感謝關於ProcessPoolExecutor的提示,該提示應該是全球性的! –