如何在Twisted中排队FTP命令?

时间:2010-11-09 00:04:40

标签: python ftp twisted ftp-client

我正在使用Twisted编写一个FTP客户端,可以下载大量文件,我正在尝试非常聪明地进行操作。但是,我一直遇到的问题是我会很快下载几个文件(有时候每批次约20个,有时约250个),然后下载会挂起,最后只有连接超时然后下载并挂起启动一遍又一遍。我正在使用DeferredSemaphore一次只下载3个文件,但我现在怀疑这可能不是避免限制服务器的正确方法。

以下是相关代码:

def downloadFiles(self, result, directory):
    # make download directory if it doesn't already exist
    if not os.path.exists(directory['filename']):
        os.makedirs(directory['filename'])

    log.msg("Downloading files in %r..." % directory['filename'])

    files = filterFiles(None, self.fileListProtocol)
    # from http://stackoverflow.com/questions/2861858/queue-remote-calls-to-a-python-twisted-perspective-broker/2862440#2862440
    # use a DeferredSemaphore to limit the number of files downloaded simultaneously from the directory to 3
    sem = DeferredSemaphore(3)
    jobs = [sem.run(self.downloadFile, f, directory) for f in files]
    d = gatherResults(jobs)
    return d

def downloadFile(self, f, directory):
    filename = os.path.join(directory['filename'], f['filename']).encode('ascii')
    log.msg('Downloading %r...' % filename)
    d = self.ftpClient.retrieveFile(filename, FTPFile(filename))
    return d

您会注意到我正在重用FTP连接(顺便主动)并使用我自己的FTPFile实例来确保当文件下载连接“丢失”(即已完成)时本地文件对象被关闭。看FTPClient我想知道我是否应该直接使用queueCommand。说实话,我在retrieveFile命令_openDataConnection之后丢失了,所以也许它已经被使用了。

有什么建议吗?谢谢!

1 个答案:

答案 0 :(得分:1)

我建议使用queueCommand,因为你建议我怀疑你使用的信号量可能会导致你的问题。我相信使用queueCommand会将你的FTPClient限制为单个活动连接(虽然我只是推测),所以如果你想快速做事,你可能想要创建一些FTPClient实例并将下载作业传递给它们。如果您使用queueStringCommand,则可以使用Deferred来确定每个客户端的位置,甚至可以在回调中为该客户端的队列添加另一个作业。