私は、リポジトリを通過する「クローラ」に取り組んできました。実行するすべてのディレクトリに対して、そのディレクトリに対して同じ処理を行うスレッドを再帰的に作成します。実際には、これはreposで検出されたすべてのディレクトリに対して非常に短期間のスレッドを作成します。 (それだけで一つのパスに関する情報を要求するために非常に時間がかかることはありません、ちょうど十それらの何千ものがあります)P4Python:同時にPERFORCEの情報を要求する複数のスレッドを使用する
ロジックは次のようになります。
import threading
import perforce as Perforce #custom perforce class
from pathlib import Path
p4 = Perforce()
p4.connect()
class Dir():
def __init__(self, path):
self.dirs = []
self.files = []
self.path = path
self.crawlers = []
def build_crawler(self):
worker = Crawler(self)
# append to class variable to keep it from being deleted
self.crawlers.append(worker)
worker.start()
class Crawler(threading.Thread):
def __init__(self, dir):
threading.Thread.__init__(self)
self.dir = dir
def run(self):
depotdirs = p4.getdepotdirs(self.dir.path)
depotfiles = p4.getdepotfiles(self.dir.path)
for p in depotdirs:
if Path(p).is_dir():
_d = Dir(self.dir, p)
self.dir.dirs.append(_d)
for p in depotfiles:
if Path(p).is_file():
f = File(p) # File is like Dir, but with less stuff, just a path.
self.dir.files.append(f)
for dir in self.dir.dirs:
dir.build_crawler()
for worker in d.crawlers:
worker.join()
は明らかに、これは完全なコードではありませんが、私は何をしているのかを表しています。
私の質問は、実際には、このPerforceクラスのインスタンスをクローラクラスの__init__
メソッドで作成して、リクエストを個別に実行できるかどうかです。今すぐ、私はjoin()
を作成したスレッドに呼び出す必要があります。これにより、完了するまで待機して、同時実行の呼び出しを回避します。
私は試してみましたが、作成できる接続の数に制限があるようです:実数はありませんが、Perforceのラインのどこかに接続が拒否されました。私は、同時リクエストの数に起因すると推測します。
本当に私は2倍だと思います:使用しているものより何万ものファイルを持つreposを表すデータモデルを作成するより良い方法があります。可能なことをしようとする場合、もしそうなら、方法。
任意の助けいただければ幸いです:)私は(それがすべてのシンプルなソリューションに過度に複雑な問題のように、infuriatingly簡単です)これを行う方法を見つけ
「Perforceがまもなく接続を拒否し始めました。これは、同時リクエストの数に起因すると思われます。どのような正確なエラーがありましたか? PERFORCEサーバのログにもメッセージがありますか? –
残念ながら私にエラーを返すことはできませんが、接続タイムアウトと関係していました。私は、PERFORCE接続ビットを可能な限り短命にして、必要なデータを与えるとすぐに強制終了させることで修正しました。私が知る限り、PERFORCEサーバのログにはメッセージはありませんでした。私は別の方法で必要なことをする方法を見つけました。下記の答えをご覧ください。 – MaVCArt