设计问题:您将如何设计定期事件系统? [关闭]

最后发布: 2008-09-23 20:52:38


问题

如果您的任务是构建支持重复事件的事件调度系统,您将如何做? 如何删除定期活动时的处理方式? 你怎么能看到未来事件何时发生?

即在创建活动时,您可以选择“每日重复”(或每周,每年等)。

请回复一个设计。 我已经习惯了Ruby / Rails,但是使用你想表达设计的任何东西。

我在接受采访时被问到这个问题,并且无法提出我喜欢的非常好的回复。

注意: 这里已经被问到/已经回答了。 但我希望得到一些更实用的细节,详情如下:

  • 如果有必要能够对重复事件的一个实例进行评论或以其他方式添加数据,那该怎么办?
  • 事件更改和删除如何工作?
  • 你如何计算未来事件的发生时间?
calendar
回答

我开始实现Martin Fowler概述的一些时态表达。 这样可以确定计划项目何时应该实际发生。 这是一种非常优雅的方式。 我最终得到的只是文章中的内容。

下一个问题是弄清楚世界上如何存储表达式。 另一个问题是当你读出表达式时,那些如何适应不那么动态的用户界面? 有人谈到将表达式序列化为BLOB,但是很难走出表达式树以了解它的含义。

解决方案(在我的例子中)是存储适合用户界面将支持的有限数量的情况的参数,并从那里使用该信息来动态生成时间表达式(可以在创建时进行序列化以进行优化)。 因此,Schedule类最终会有几个参数,如偏移量,开始日期,结束日期,星期几等......然后您可以生成Temporal表达式来完成艰苦的工作。

至于具有任务的实例,有一个“服务”可以生成N天的任务。 由于这是与现有系统的集成,并且需要所有实例,因此这是有道理的。 但是,像这样的API可以很容易地用于投影重复,而不存储所有实例。


回答

在我管理项目的数据库结束之前,我必须这样做。 我要求将每个事件存储为单独的事件。 这允许您只删除一个事件,或者您可以移动范围。 删除倍数比尝试修改单个事件并将其变为两个要容易得多。 然后我们能够创建另一个表,其中只有一个包含重现信息的recurrenceID。


回答

@Joe Van Dyk问:“你能看到未来,看看即将到来的活动何时会出现?”

如果你想看到/显示事件的下n OCCURENCES他们将不得不要么一)在预先计算和存储在某个地方或b)可以实时计算和显示。 任何晚上的框架都是一样的。

a)的缺点是你必须在某处限制它,之后你必须使用b)。 更容易使用b)开始使用。

调度系统不需要这些信息,只需要知道下一个事件的时间。


回答

保存事件时,我会将计划保存到商店(我们称之为“ 计划 ”,我会计算下次启动事件的时间并保存,例如“ 事件 ”。然后我会查看“ 事件 ”并找出下一个事件何时发生并在此之前进入睡眠状态。

当应用程序“唤醒”时,它将计算事件何时应再次发生,再次将其存储在“ 事件 ”中,然后执行该事件。

重复。

如果在睡眠时创建事件,则中断并重新计算睡眠。

如果应用程序正在启动或从睡眠事件或类似事件中恢复,请检查“ 事件 ”以查看已通过的事件并采取相应措施(取决于您要对错过的事件执行的操作)。

像这样的东西会很灵活,不会占用不必要的CPU周期。


回答

脱了我的头脑(在打字/思考时修改了几个东西):

确定所需的最小重复分辨率; 这就是应用运行的频率。 也许是每天,也许是每五分钟一次。

对于每个定期事件,如果需要,存储最近的运行时间,运行间隔和其他好东西,如到期时间。

每次应用程序运行时,它都会检查所有事件,比较(今天/现在+ recurrenceResolution)和(recentRunTime + runInterval),如果它们重合,则触发事件。


回答

当我喃喃年前写了自己是一个日历应用程序,我基本上只是从cron偷走了调度机制和使用,对于经常性的事件。 例如,除了1月份之外的每个月的第二个星期六发生的事情将包括指令“repeat = * 2-12 8-14 6”(每年,2-12个月,第2个星期从8日到14日,因为我在一周的几天使用了0编号,所以星期六有6个星期六。

虽然这使得确定事件是否在任何给定日期发生变得非常容易,但是它不能处理“每N天”重复发生,并且对于不是unix-savvy的用户来说也不太直观。

为了处理单个事件实例和删除/重新安排的唯一数据,我只是跟踪计算了多远的事件并将结果事件存储在数据库中,然后可以在这些事件中修改,移动或删除事件而不影响原始的经常性事件信息。 添加新的定期事件时,会立即计算所有实例,直到现有的“最后计算”日期为止。

我没有声称这是最好的方法,但它是一种方式,并且在我之前提到的限制范围内运行良好。


回答

如果你有一个简单的reoccuring事件,比如每天,每周或每周几天,那么在scheduler / cron / at functionallity中使用buildt有什么问题? 创建可执行/控制台应用程序并设置何时运行它? 没有复杂的日历,事件或时间管理。

:)

// w ^