2010-07-14 68 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