2016-09-09 1 views
0

Ich habe an einem "Crawler" der Art gearbeitet, die durch unser Repository geht und Verzeichnisse und Dateien auflistet, wie es geht. Für jedes Verzeichnis, auf das es zugreift, erstellt es einen Thread, der dasselbe für das Verzeichnis usw. rekursiv tut. Effektiv erzeugt dies einen sehr kurzlebigen Thread für jedes Verzeichnis, das in den Repos angetroffen wird. (Es dauert nicht sehr lange Informationen zu ersuchen, für nur einen Weg gibt es nur Zehntausende von ihnen)P4Python: Verwenden Sie mehrere Threads, die zur gleichen Zeit forcieren Informationen anfordern

Die Logik sieht wie folgt aus:

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

Offensichtlich ist dies nicht vollständiger Code, sondern es repräsentiert, was ich tue.

Meine Frage ist wirklich, ob ich eine Instanz dieser Perforce-Klasse in der __init__-Methode der Crawler-Klasse erstellen kann, so dass Anforderungen separat durchgeführt werden können. Im Moment muss ich join() auf den erstellten Threads aufrufen, so dass sie auf den Abschluss warten, um gleichzeitige Zwangsaufrufe zu vermeiden.

Ich habe es ausprobiert, aber es scheint wie gibt es eine Grenze für die Anzahl der Verbindungen, die Sie erstellen können: Ich habe keine feste Zahl, aber irgendwo entlang der Linie begonnen Perforce gerade ablehnen Verbindungen, die Ich nehme an, ist aufgrund der Anzahl der gleichzeitigen Anfragen.

Was ich eigentlich möchte, ist zweifach: Gibt es eine bessere Möglichkeit, ein Datenmodell zu erstellen, das Repos mit zehntausenden von Dateien repräsentiert, als das, das ich benutze, und was ich bin versuchen zu tun, und wenn ja, wie.

Jede Hilfe wäre sehr geschätzt :)

+0

Können Sie mehr Genauigkeit hinzufügen? Perforce hat gerade angefangen, Verbindungen abzuweisen, was vermutlich auf die Anzahl gleichzeitiger Anfragen zurückzuführen ist? Welchen genauen Fehler haben Sie erhalten? Gab es auch Nachrichten im Perforce-Serverprotokoll? usw. –

+0

Ich bekomme es leider nicht mehr - aber es hatte mit Verbindungstimeouts zu tun. Ich habe das behoben, indem ich die Verbindung so kurz wie möglich gemacht habe, um sie zu beenden, sobald sie fertig ist, und mir die Daten zu geben, die ich brauche. Soweit ich das beurteilen kann, gab es keine Meldungen im Serverprotokoll, nein - ich habe herausgefunden, wie ich das tun kann, was ich brauche, siehe unten. – MaVCArt

Antwort

2

ich herausgefunden hat, wie dies zu tun (es ist aufreizend einfach, wie bei allen einfachen Lösungen zu übermäßig komplizierten Problemen):

ein Datenmodell zu erstellen, die enthalten Dir und File Klassen, die ein ganzes Depot mit Tausenden von Dateien darstellen, rufen Sie einfach p4.run("files", "-e", path + "\\...") an. Dies wird rekursiv eine Liste aller Dateien in path zurückgeben. Von dort müssen Sie nur über jeden zurückgegebenen Pfad iterieren und von dort aus Ihr Datenmodell aufbauen.

Hoffe, das hilft jemandem irgendwann.

Verwandte Themen