2017-08-02 4 views
1

Ich habe eine Funktion, die einen Shell-Befehl ausführt, um einen Server auf dem Computer bereitzustellen. Diese Funktion nimmt die folgenden Parameter:Polling für eine maximale Wartezeit, außer Bedingung in Python 2.7

  • Verzeichnispfad
  • Befehl
  • Server-Port
  • Wartezeit

Jetzt, nachdem die command wird aus dem Inneren des directory path ausgeführt, die Funktion time.sleep s bis wait time und prüft dann auf Prozesse, die auf dem server port hören.

Während diese Methode effektiv ist, verschwendet sie viel Zeit für command s, wo die Zeit für den Start erheblich geringer ist als wait time.

Ich plante, einen Kellner zu schaffen, der auf ein Maximum von wait time warten wird, aber die in regelmäßigen kleinen Abständen abfragen. Wenn Prozesse gefunden werden, bevor wait time vorbei ist, möchte ich, dass die Funktion nur von diesem Punkt aus sicher zurückkehrt und den Prozess bis zum Ende nicht blockiert.

Ich habe keine Ahnung, wie ich mit dem gleichen verfahren soll. Der nächste, den ich mir vorstellen kann, ist das Erstellen eines Umfrageobjekts (unter Verwendung von select.poll), aber ein Beispiel (oder ein Paket, falls verfügbar) würde mir sehr helfen.

Meine aktuelle Funktion tut so etwas wie:

run_local_command(
    ['nohup', start_command, ">>", logfile, '2>>', errfile, '&'], 
    explanation="Starting server", 
    target_dir=target_dir 
) 
time.sleep(wait_time) 
# Get the PIDs listening to the specific port 
processes = [ 
    p for p in psutil.net_connections(kind='inet') 
    if p.laddr[1] == port and p.status == 'LISTEN' 
] 
logger.debug("Logged following processes for the service port: %s", processes) 
pids = [x.pid for x in processes if x.pid is not None] 

Antwort

1

Was ich zu warten, verwenden in der Regel, bis eine Bedingung erfüllt ist oder bis ein Timeout ist eine kleine Funktion wie folgt aus:

def wait_condition(condition, timeout=5.0, granularity=0.3, time_factory=time): 
    end_time = time.time() + timeout # compute the maximal end time 
    status = condition()    # first condition check, no need to wait if condition already True 
    while not status and time.time() < end_time: # loop until the condition is false and timeout not exhausted 
     time.sleep(granularity)  # release CPU cycles 
     status = condition()   # check condition 
    return status      # at the end, be nice and return the final condition status : True = condition satisfied, False = timeout occurred. 

So, indem Sie dieser Methode eine Methode condition geben, die True zurückgibt, wenn sie aufgerufen wird und Bedingung erfüllt ist (und False, wenn nicht).

Dies wird eine Schleife (und einige Pause machen, um zu viel CPU-Belegung zu vermeiden) und am Ende der Zeitüberschreitung ausgehen oder wenn Bedingung True ist.

In Ihrem Fall wird die Bedingung Methode wahrscheinlich so etwas wie dies tun:

def port_opened(): 
    return [p for p in psutil.net_connections(kind='inet') if p.laddr[1] == port and p.status == 'LISTEN'] # assuming that an empty list is False in python 
+0

Es scheint ein einfacher Ansatz ... Keine Ahnung, warum ich in tauchte https://stackoverflow.com/q/38499261/1190388 – hjpotter92

+0

@ hjpotter92 die verknüpfte Antwort kann nützlich sein, um zu warten, dass mehrere Bedingungen erreicht werden, Ihr Problem scheint nur eine Stoppbedingung zu haben, in diesem Fall [KISS] (https://en.wikipedia.org/wiki/KISS_principle) ist ein gutes Prinzip :) –