2

多くのファイルをダウンロードする 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以降まで迷ったので、もしかしたら既に使われているのかもしれません。

助言がありますか?ありがとう!

4

1 に答える 1

1

あなたが使用しているセマフォがおそらく問題を引き起こしていると思われると示唆したように、queueCommand を使用することをお勧めします。queueCommand を使用すると、FTPClient がアクティブな接続を 1 つに制限されると思います (推測にすぎませんが)。そのため、迅速に処理したい場合は、いくつかの FTPClient インスタンスを作成し、それらにダウンロード ジョブを渡すことを検討することをお勧めします。queueStringCommandを使用すると、各クライアントがどこにいるかを判断するために使用できる Deferred を取得し、コールバックでそのクライアントのキューに別のジョブを追加することさえできます。

于 2010-11-09T02:56:02.407 に答える