Skip to main content
 首页 » 编程设计

python之Twisted Producer 延迟写入

2025年05月04日6powertoolsteam

在 FTP 服务器示例中,它使用 IWriteFile,它期望消​​费者使用我现在拥有的代码缓冲并将 4mb block 发送到服务器,但是生产者写入似乎并不期望延迟,而是同步写入是否安全使用延迟?

代码

# Deals with giving the FTP Connection a FileConsumer then the File Consumer takes over 
class EmailWriter(object): 
    implements(IWriteFile) 
 
    def __init__(self, filename): 
        print "EmailWriter: %s" % filename 
        self.filename = filename 
        self._receive = False 
 
    def receive(self): 
        assert not self._receive, "Can only call IWriteFile.receive *once* per instance" 
        self._receive = True 
        # FileConsumer will close the file object 
        self.consumer = EmailConsumer("user@gmail.com", "password", "gmail.com", "smtp.gmail.com", 587, self.filename) 
        return defer.succeed(self.consumer) 
 
    def close(self): 
        # signals that the upload is done 
        pass 
 
 
# Writing Data 
class EmailConsumer(object): 
    # implements 
    # Consumer 
    def __init__(self, path, server): 
        self.path = path 
        self.json_db = JsonDB(path) 
        self.server = server 
 
        self.indexes = {} 
        self.blocks = 0 
 
        self.start = False 
        self.stop = False 
        self.producer = None 
        self.streaming = None 
 
 
 
 
    def registerProducer(self, producer, streaming): 
        # start expecting data 
        assert (self.stop == False), "Cannot register multiple times..." 
        self.start = True 
        self.producer = producer 
        self.streaming = streaming 
 
 
    def unregisterProducer(self): 
        # stop expecting data 
        self.start = False 
        self.stop = True 
        self.producer = None 
        self.streming = None 
 
    def write(self, bytes): 
        # recieve data 
        self.buffer += bytes 
        if len(self.buffer) > BLOCK_SIZE: 
            self.blocks += 1 
            d = self.server.send_file(self.buffer) 
            d.addCallback(self._done_uploadng, hash(self.buffer), self.blocks) 
            self.buffer = "" 
 
    def self._done_uploadng(self, result, hash, block): 
        self.index[block] = (hash, self.server.account) 
        self.json_db.set_data("index", self.index) 
 
        return result 

请您参考如下方法:

简短的回答是肯定的,返回一个 Deferred 是安全的。

在 twisted.internet.interfaces.IConsumer 的文档中还有另一个提示:

def write(data): 
    """ 
    The producer will write data by calling this method. 
 
    The implementation must be non-blocking and perform whatever 
    buffering is necessary.  If the producer has provided enough data 
    for now and it is a L{IPushProducer}, the consumer may call its 
    C{pauseProducing} method. 
    """ 

所以我建议您使用 self.producer.pauseProducing() 和 self.producer.resumeProducing() 包装对 self.server.send_file() 的调用。这样您就不会以可重入的方式调用它,这对于大文件会发生。