2010-07-14 89 views
2

關於Python Twisted框架,有人可以向我解釋如何向消費者異步寫入非常大的數據字符串,比如protocol.transport對象?使用延遲的Python扭曲異步寫入

我想我缺少的是一個write(data_chunk)函數返回Deferred。這是我想做些什麼:

data_block = get_lots_and_lots_data() 
CHUNK_SIZE = 1024 # write 1-K at a time. 
def write_chunk(data, i): 
    d = transport.deferredWrite(data[i:i+CHUNK_SIZE]) 
    d.addCallback(write_chunk, data, i+1) 
write_chunk(data, 0) 

但是,在扭曲API /文檔轉悠了一天之後,我似乎無法找到像deferredWrite等價什麼。我錯過了什麼?

回答

1

Twisted中處理大量數據的方式是使用Producer/Consumer APIs。這不會給你一個返回Deferredwrite方法,但它會告訴你什麼時候寫更多的數據。

8

正如Jean-Paul所說,你應該使用IProducer and IConsumer,但是你也應該注意到缺少deferredWrite是有點故意的遺漏。

一方面,對於數據的潛在每一個字節是被寫入創建Deferred是一個性能問題:我們試過在web2項目,並發現它與整個系統中最顯著的性能問題,我們都試圖避免這個錯誤,因爲我們將web2代碼返回twisted.web

更重要的是,具有被返回的write「完成」當Deferred將提供一個錯誤的印象:該線的另一端有收到你已經發送的數據。沒有合理的方法來辨別這一點。代理,智能路由器,應用程序錯誤和所有網絡設計方式都可能欺騙你,讓你認爲你的數據實際上到達了連接的另一端,即使它從未得到處理。如果您需要知道另一端已經處理了您的數據,請確保您的應用程序協議有一個確認消息,該消息僅在數據已被接收和處理後纔會發送。

在這種代碼中使用生產者和消費者的主要原因是爲了避免首先分配內存。如果你的代碼真的把它要寫入其對等體的所有數據讀入內存中的一個巨大字符串(data_block = get_lots_and_lots_data()相當直接的暗示),那麼你不會因爲做transport.write(data_block)而損失太多。交通工具會醒來,並儘可能多地發送大量數據。另外,您可以簡單地執行transport.write(hugeString)然後transport.loseConnection(),並且只有在所有數據已發送或連接中斷後,傳輸纔會真正斷開連接。 (還是那句話:如果你不等待確認,你不會知道,如果得到的數據有,但如果你只是想一些字節轉儲到插座,而忘記了它,這個工作好。)

如果get_lots_and_lots_data()實際上是讀取文件,則可以使用包含的FileSender類。如果它有點像文件但不完全,the implementation of FileSender可能是一個有用的例子。

+1

哇,沒想到有太多的延期了。謝謝,雕文。用Jean-Paul給出的指針和FileSender的示例代碼,我的頭腦在混亂中扭曲得更少。 – 2010-07-17 06:50:09

+0

+1減少扭曲的頭腦 - 這就是Twisted給你的。 – 2010-07-17 11:00:36