2017-12-28 30 views
0

次のコードでは、特定の制限時間を超過すると、メソッド 'execute'に渡される関数(バー)の実行を停止するクラス 'TimedExecutor'を作成しようとしています。ただし、エラーメッセージが表示されても、プログラムの実行は停止しません。シグナルアラームでエラーが発生しない

注:外部モジュールから提供されているので、bar()機能に変更を加えてはなりません。

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) 

答えて

0

あなたのファンクタは、あなたが致命的と思われる例外を飲み込んでいます。

それbar()次いでプリントとはTimeoutListenerコンテキストマネージャによって発生した誤差を破棄し、そのループの1つに句以外です。その後、ループが再開されます。

bar()は、あなたのTimedExecutorが発生させる可能性のある例外を認識していない可能性があります。その代わり、bar().execute()を呼び出すの呼び出し側はそれを認識しておく必要があります

from aditya.utils import TimedExecutor, TimeoutException 

... 

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

このソリューションは、あまりにも動作するようには思えません。作業コードを提供できますか? – Aditya

+0

解決策は単に 'bar()'の中からtry/exceptブロックを削除することです。私が提示したのは擬似コードリファクターでした。 – pilcrow

+0

いいえ、関数bar()は変更できません。別のモジュールからのものです。実行のタイミングを処理するコードを設計する必要があります。 – Aditya

関連する問題