2013-01-04 23 views
2

假設,(使用龍捲風)一個想要傳輸大數據到慢客戶端,並打印傳輸的數據量。我寫了這個簡單的代碼用於此目的:終於阻止龍捲風發電機引擎不工作

from tornado import web, ioloop, gen 

class MainHandler(web.RequestHandler): 
    @web.asynchronous 
    @gen.engine 
    def get(self): 
     print '(start' 
     try: 
      for i in xrange(100): 
       self.write('*' * 100000) # write ~100KB of data 
       yield gen.Task(self.flush) # wait for reciever to recieve 
       print '- wrote', i 
     finally: 
      print '| finally' 
      self.finish() 
     print ') finish' 

application = web.Application([ 
    (r"/", MainHandler), 
    ]) 

application.listen(8888) 
ioloop.IOLoop.instance().start() 

但沒有按預期工作的代碼,例如這個簡單的客戶機:

req = urlopen('http://127.0.0.1:8888/') 
sys.exit() # exit without reading response 

服務器輸出該:

(start 
- wrote 0 
- wrote 1 
- wrote 2 
WARNING:root:Read error on 7: [Errno 104] Connection reset by peer 
WARNING:root:error on read 
Traceback (most recent call last): 
    File "/usr/local/lib/python2.7/dist-packages/tornado-2.4.1-py2.7.egg/tornado/iostream.py", line 361, in _handle_read 
    if self._read_to_buffer() == 0: 
    File "/usr/local/lib/python2.7/dist-packages/tornado-2.4.1-py2.7.egg/tornado/iostream.py", line 428, in _read_to_buffer 
    chunk = self._read_from_socket() 
    File "/usr/local/lib/python2.7/dist-packages/tornado-2.4.1-py2.7.egg/tornado/iostream.py", line 409, in _read_from_socket 
    chunk = self.socket.recv(self.read_chunk_size) 
error: [Errno 104] Connection reset by peer 

但既不finally也不finish被打印。

什麼問題?

UPDATE:

我注意到,如果我實現on_connection_close處理程序進行處理,該on_connection_close回調將被調用,並打印在控制檯中沒有錯誤。但是這個函數有什麼魔力? (我已經定義了RequestHandler空身)。

更大的答案:爲什麼我的發電機不是close d?它是垃圾收集還是不收? PEP-342說最終阻止應該在任何情況下執行。

+0

我想發電機還在等待更多的輸入? –

+0

@Martijn即使我用信號(或Control + C)關閉服務器,finally塊也不會運行。我如何強制終止阻止執行? –

+0

我懷疑它*運行,但那個時候'stdout'已經關閉了。你有沒有嘗試打開一個明確的專用文件來測試? –

回答

1

發電機與finally子句實現使__del__在Python版本< = 3.3,且具有其它析構函數所有限制 - 它們不保證將在參考週期的存在及時如果在所有執行。在Python 3.4中,這得到了改進(http://www.python.org/dev/peps/pep-0442/),並且生成器的finally子句運行得更加可靠。