P4Python:使用同时请求perforce信息的多个线程
P4Python: use multiple threads that request perforce information at the same time
我一直在研究 "crawler" 通过我们的存储库并列出目录和文件的各种方式。对于它遇到的每个目录,它都会创建一个线程,该线程递归地对该目录执行相同的操作,依此类推。实际上,这会为存储库中遇到的每个目录创建一个非常短暂的线程。 (一条路索取信息的时间不会很长,就几万条)
逻辑如下:
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 class 的 __init__
方法中创建这个 Perforce class 的实例,以便可以单独完成请求。现在,我必须在创建的线程上调用 join()
以便它们等待完成,以避免并发 perforce 调用。
我已经试过了,但似乎您可以创建的连接数量是有限制的:我没有确切的数字,但是 Perforce 刚开始直接拒绝连接,我认为这是由于并发请求的数量。
我想我真正要问的是两方面的:有没有比我正在使用的更好的方法来创建代表包含数万个文件的存储库的数据模型,这就是我'我正在努力做到可能,如果可以,怎么做。
任何帮助将不胜感激:)
我找到了如何做到这一点(它非常简单,就像对过于复杂的问题的所有简单解决方案一样):
要构建包含 Dir
和 File
类 的数据模型,代表具有数千个文件的整个软件仓库,只需调用 p4.run("files", "-e", path + "\...")
。
这将递归地 return path
中每个文件的列表。从那里您需要做的就是遍历每个 returned 路径并从那里构建您的数据模型。
希望这对某些人有所帮助。
我一直在研究 "crawler" 通过我们的存储库并列出目录和文件的各种方式。对于它遇到的每个目录,它都会创建一个线程,该线程递归地对该目录执行相同的操作,依此类推。实际上,这会为存储库中遇到的每个目录创建一个非常短暂的线程。 (一条路索取信息的时间不会很长,就几万条)
逻辑如下:
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 class 的 __init__
方法中创建这个 Perforce class 的实例,以便可以单独完成请求。现在,我必须在创建的线程上调用 join()
以便它们等待完成,以避免并发 perforce 调用。
我已经试过了,但似乎您可以创建的连接数量是有限制的:我没有确切的数字,但是 Perforce 刚开始直接拒绝连接,我认为这是由于并发请求的数量。
我想我真正要问的是两方面的:有没有比我正在使用的更好的方法来创建代表包含数万个文件的存储库的数据模型,这就是我'我正在努力做到可能,如果可以,怎么做。
任何帮助将不胜感激:)
我找到了如何做到这一点(它非常简单,就像对过于复杂的问题的所有简单解决方案一样):
要构建包含 Dir
和 File
类 的数据模型,代表具有数千个文件的整个软件仓库,只需调用 p4.run("files", "-e", path + "\...")
。
这将递归地 return path
中每个文件的列表。从那里您需要做的就是遍历每个 returned 路径并从那里构建您的数据模型。
希望这对某些人有所帮助。