2017-12-28 5 views
0

Im folgenden Code versuche ich eine Klasse 'TimedExecutor' zu erstellen, die die Ausführung der Funktion (bar), die an ihre Methode 'execute' übergeben wurde, stoppt, wenn ein bestimmtes Zeitlimit überschritten wird. Aber die Programmausführung wird nicht beendet, obwohl die Fehlermeldung angezeigt wird.Signalalarm löst keinen Fehler aus

Hinweis: Die Funktion bar() darf nicht verändert werden, da sie von einem externen Modul zur Verfügung gestellt wird.

import signal 
import time 

class MyError(Exception): 
    """Base error""" 

class MyInheritedError(MyError): 
    """Class to inherit from base error""" 


class TimeoutListener(object): 
    def __init__(self, timeout_seconds, error_message="Timeout executing."): 
    self.timeout_seconds = timeout_seconds 
    self.error_message = error_message 
    self.alarm = None 

    def __enter__(self): 
    signal.signal(signal.SIGALRM, self._handle_timeout) 
    signal.alarm(self.timeout_seconds) 

    def __exit__(self, listener_type, value, traceback): 
    # Disable the alarm. 
    if self.alarm: 
     self.alarm = None 
    else: 
     signal.alarm(0) 

    def _handle_timeout(self, signum, frame): 
    print("Got the signum %s with frame: %s" % (signum, frame)) 
    raise MyInheritedError(self.error_message + "aditya") 


class TimedExecutor(object): 
    @staticmethod 
    def execute(timeout_secs, functor, *args, **kwargs): 
    msg = "Timeout executing method - %s." % functor.__name__ 
    timeout_signal = TimeoutListener(timeout_secs, error_message=msg) 
    try: 
     with timeout_signal: 
     output = functor(*args, **kwargs) 
    except MyInheritedError as ex: 
     print("%s did not complete in %s: %s." 
      % (functor.__name__, timeout_secs, repr(ex))) 
     raise 
    return output 


def bar(): 
    for _ in range(5): 
    try: 
     time.sleep(1) 
     print("SLEEPING") 
    except MyInheritedError as ex: 
     print ex 


ob = TimedExecutor.execute(2, bar) 

Antwort

0

Ihr Funktor schluckt die Ausnahme, die Sie beabsichtigen, tödlich zu sein.

Es ist bar() ‚s außer Klausel in eines seines Schleife, die drucken und dann den Fehler durch die TimeoutListener Kontextmanager angehoben verwirft. Dann wird die Schleife fortgesetzt.

bar() sollte wahrscheinlich nicht die Ausnahme kennen, die Ihre TimedExecutor erhöhen kann. Stattdessen bar() ‚s Anrufer, .execute() sollte es beachten Sie ruft:

from aditya.utils import TimedExecutor, TimeoutException 

... 

try: 
    TimedExecutor.execute(2, bar) 
except TimeoutException: 
    print("Timed out executing bar") 
+0

Diese Lösung nicht zu arbeiten scheint. Könnten Sie einen Arbeitscode angeben? – Aditya

+0

Die Lösung besteht lediglich darin, den try/except-Block aus 'bar()' zu entfernen. Was ich vorstellte, war ein Pseudocode-Refactor. – pilcrow

+0

Nein, die Funktionsleiste() kann nicht geändert werden, sie stammt von einem anderen Modul. Ich muss einen Code entwerfen, der das Timing der Ausführung behandelt. – Aditya

Verwandte Themen