P4Python:使用多个线程同时请求perforce信息

时间:2016-09-09 09:34:07

标签: python multithreading perforce p4python

我一直在研究通过我们的存储库的各种“爬虫”,并列出目录和文件。对于它所遇到的每个目录,它会创建一个对该目录执行相同操作的线程,依此类推,递归。实际上,这会为repos中遇到的每个目录创建一个非常短暂的线程。 (在一条路径上请求信息不需要很长时间,只有几万条路径)

逻辑如下:

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()

显然这不是完整的代码,但它代表了我正在做的事情。

我的问题是我是否可以在Crawler类的__init__方法中创建此Perforce类的实例,以便可以单独完成请求。现在,我必须在创建的线程上调用join(),以便它们等待完成,以避免并发perforce调用。

我已经尝试过了,但似乎你可以创建多少个连接是有限制的:我没有一个固定的数字,但在Perforce的某个地方刚开始直接拒绝连接,我假设是由于并发请求的数量。

我真正想问的是,我认为是双重的:是否有更好的方法来创建一个数据模型,代表一个包含数万个文件的回购,而不是我正在使用的文件,这就是我正在尝试的如何做,如果可能,怎么做。

非常感谢任何帮助:)

1 个答案:

答案 0 :(得分:2)

我发现了如何做到这一点(它非常简单,就像对过于复杂的问题的所有简单解决方案一样):

要构建包含代表包含数千个文件的整个软件仓库的DirFile类的数据模型,只需调用p4.run("files", "-e", path + "\\...")即可。 这将以递归方式返回path中每个文件的列表。从那里你需要做的就是迭代每个返回的路径并从那里构建你的数据模型。

希望这会在某些时候帮助某人。