2012-06-20 32 views
0

我正在學習App Engine任務隊列。我的應用程序有處理文檔的任務。每項任務大約需要5-10分鐘才能完成。我的目標是通過網頁監控每項任務的進度。爲什麼我的應用程序引擎任務會阻止頁面刷新?

作爲一項測試,我用一個簡單的循環對push queue tutorial code進行了修改(見下文)。當提交「分析器頁面」表單時,會啓動一個新的「事務循環」任務。

我很驚訝異步的'事務循環'阻止了'分析器頁'的刷新,直到任務完成。

我有兩個問題:

  1. 爲什麼異步任務停止頁面刷新?

    我對任務背後的實現的幼稚看法是,每個任務都是一個預定的線程或進程,'transaction loop'線程會在數據存儲io期間阻塞,讓'分析器頁面'線程刷新。 (這是不感興趣的,因爲我們的最終代碼將與此測試顯着不同)

  2. 使用數據存儲/ memcache來記錄任務進度似乎相當重,特別是在寫配額方面 - 有沒有更好的方法去做這個?

感謝,

布賴恩


測試開發服務器1.6上:

from google.appengine.api import taskqueue 
from google.appengine.ext import db 
from google.appengine.ext import webapp 

class Counter(db.Model): 
    count = db.IntegerProperty(indexed=False) 

class Analyser(webapp.RequestHandler): 
    # Analyser Page -- Page refresh (get) only completes after task is called 
    def get(self): 

     self.response.write("<html> <body>") 

     # My first guess was that calling counter.put() blocked the Counter.all() 
     # call to the datastore. 
     # However commenting the following code had the same effect. 

     # self.response.write("Counters:<br>") 
     # counters = Counter.all() 
     # for counter in counters: 
     # self.response.write(str(counter.count) + "<br>") 

     self.response.write("<form action=\"/api/analyse\" method=\"post\"> \ 
          Key: <input type=\"text\" name=\"key\" /><br /> \ 
          <input type=\"submit\" value=\"Submit\" /> \ 
         </form>") 

     self.response.write("</body> </html>") 

def post(self): 
    key = self.request.get('key') 
    # Add the task to the default queue. 
    taskqueue.add(url='/analyse_worker', params={'key': key}) 
    self.response.write("Added task with key:" + key) 

class AnalyserWorker(webapp.RequestHandler): 
    def post(self): # should run at most 1/s 
     key = self.request.get('key') 

    def txn(): 
     counter = Counter.get_by_key_name(key) 
     if counter is None: 
      counter = Counter(key_name=key, count=1) 
     else: 
      counter.count += 1 
     counter.put() 

    # Transaction loop 
    for i in range(0,200): 
     db.run_in_transaction(txn) 

回答

2

開發應用程序服務器是單線程的,這就是爲什麼你刷新頁面被阻塞,直到任務完成。

+0

嗨斯圖爾特,感謝您的答覆。這就說得通了。雖然此功能使開發任務密集型應用程序變得非常棘手。你有什麼建議如何開發這個?我當然可以在開發中模擬(存根?)任務,但如果有標準方法,那將會很好。你可以運行應用引擎虛擬機嗎? – brif

相關問題