2

したがって、ここにある質問への回答で提案されているように、cron-like-scheduler を作成しました。

PythonでCronのようなスケジューラを取得するにはどうすればよいですか?

でも、イベントが発生したら、別のイベントを削除したいときもある....

この機能を作成するにはどうすればよいですか?...基本的に、一度作成したら、どうすればイベントを削除できますか?

また....イベントからイベントを作成するのに問題があります。基本的に、ここでの私の目標は、イベントを使用して 1 時間ごとにファイルを解析することです。これは、他のイベントを実行したい時間を保持しています....そのため、この 1 時間ごとのイベント内から新しいイベントを作成したいと思います... .しかし、それらは作成された後に消えるようです....

ありがとう!

4

1 に答える 1

0

それはすべて、実行中の cronjob を実際にどのように実装しているかによって異なります。しかし、イベントが他のイベントを変更できるようにしたい場合は、3 つのオプションを考えることができます。

1. cron への参照を関数に渡します

CronTab クラスは、イベントがそれを「検査」できる方法を提供する必要があります。最良のオプションは、キーワード引数を「cron」引数で拡張し、次のように関数に渡すことです。

class CronTab(object):
    def __init__(self, *events):
        self.events = events
        for event in self.events:
             event.kwargs['cron'] = self
# rest of the calss remains unmodified

そうすることで、実行中の Crontab から呼び出されるすべての関数に、それを実行している cron への参照を含む「cron」パラメーターが渡されます。

2.「プレラン」マーシャルを追加します

CronTab クラスを拡張して、特定のスケジュールでイベントを実行するだけでなく、それらのイベントの前に他の関数を呼び出すこともできます。イベントのインスタンスを取得し、Trueそれを実行するために戻る必要がある関数。それらのいずれかが他の何かを返す場合、問題のイベントは実行されません。

そのための基本的な(そしてテストされていない)実装は次のようになります。

class CronTab(object):
    def __init__(self, *events, marshalls=None):
        self.events = events
        if marshalls is not None:
            # marshalls must be a list of callables that return True or False
            self.marshalls = marshalls
        else
            self.marshalls = []

    def run(self):
        t=datetime(*datetime.now().timetuple()[:5])
        while 1:
            for e in self.events:
                if all([x(e) for x in self.marshalls]):
                    e.check(t)

            t += timedelta(minutes=1)
            while datetime.now() < t:
                time.sleep((t - datetime.now()).seconds)

明らかにこれを実装するためのより良い方法があります。たとえば、reduce操作を実行して、いずれかのイベントが False を返した後で、すべてのイベントのすべてのマーシャルを実行しないようにします。しかし、これはあなたを正しい方向に向けるはずです。

CronTab クラスが実際にイベントのインスタンスを呼び出すよりも多くの作業を行った場合、checkまたは少なくとも実行のチェックを実際のイベントの実行に分離した場合、これを実装する方が簡単かもしれませんが、元のコードを変更したくありませんでした。それだけ。

3. イベントにフックを提供する

これは基本的に前のソリューションと同じですが、より「きめの細かい」ソリューションです。実行前のマーシャルのリストを 1 つだけ持つ代わりに、複数のリストを持つことになります。あなた自身のニーズに合わせて調整できる正確な量と詳細ですが、ここではあなたの要求に基づいた私の見解を示します.

一般的な「プレラン マーシャル」に加えて、イベント名ごとにそのようなリストを 1 つ持つことができます。イベントを実行する前に、すべての一般的な「プレラン マーシャル」だけでなく、イベント固有のものも実行します。

これを実装する 1 つの方法は、「事前実行マーシャル」リストをリストの辞書にして、そのようなリストを管理するいくつかのメソッドを提供することです。このようなもの:

class CronTab(object):
    def __init__(self, *events, marshalls=None):
        self.events = events
        self.marshalls = dict()
        if marshalls is not None:
            # marshalls must be a list of callables that return True or False
            self.marshalls['__general'] = marshalls
        else
            self.marshalls['__general'] = []

    # event is a string with the name of the event you want to marshall
    # or None if you want to marshall all of them 
    def register(self, callback, event=None):
        if event = None:
            self.marshalls['__general'].append(callback)
        else:
            self.marshalls.setdefault(event, list()).append(callback)

    def run(self):
        t=datetime(*datetime.now().timetuple()[:5])
        while 1:
            for e in self.events:
                if all([x(e) for x in self.marshalls['__general']]) and
                   all([x(e) for x in self.marshalls[e.name]]):
                    # the above assumes e.name exists (not in reference implementation)
                    e.check(t)

        t += timedelta(minutes=1)
        while datetime.now() < t:
            time.sleep((t - datetime.now()).seconds)

同じように、実行後のフックやその他の奇妙なものを必要に応じて追加できます。


イベントが消えるという質問に関して、問題をさらにトラブルシューティングできるように、コードをいくつか示してください。

于 2012-07-21T04:02:03.710 に答える