从python中类似cron的调度程序中删除事件



因此,我创建了一个类似cron的调度器,正如这里的问题答案所建议的那样:

如何在Python中获得类似Cron的调度器?

但有时,如果某个事件发生,我会删除另一个事件。。。。

我将如何创建此功能?。。。。基本上,一旦创建,我如何删除事件?

此外。。。。我在从活动中制作活动时遇到问题。基本上,我在这里的目标是每小时使用一个事件来解析一个文件,其中包含了我想做其他事件的时间。。。。所以我想在这个每小时一次的活动中创建新的活动。。。。但它们似乎在被创造后就消失了。。。。

谢谢!

这一切都取决于您实际如何实现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,或者至少将run的检查与实际运行事件脱钩,那么实现这一点也可能更容易,但我不想对原始代码进行太多修改。

3.提供事件挂钩

这与之前的解决方案基本相同,但更加"细粒度"。与其只有一个预运行编组的列表,不如有几个列表。您可以根据自己的需求定制确切的数量和细节,但以下是我根据您的要求所做的选择。

除了常规的"预运行编组"之外,每个事件名称还可以有一个这样的列表。在运行事件之前,不仅要运行所有常规的"预运行编组",还要运行特定于该事件的编组。

实现这一点的一种方法是将"预运行编组"列表制作成列表词典,并提供一些管理此类列表的方法。类似这样的东西:

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)

用同样的方法,你可以添加跑步后挂钩和其他你认为合适的奇怪东西。


关于您关于事件消失的问题,请向我们展示一些代码,以便能够进一步解决该问题。

最新更新