48

如果你的任务是构建一个支持重复事件的事件调度系统,你会怎么做?当一个重复的事件被删除时,你如何处理?你怎么能看到未来的事件何时发生?

即创建事件时,您可以选择“每天重复”(或每周、每年等)。

请每个响应一个设计。我习惯了 Ruby/Rails,但使用任何你想表达的设计。

我在一次采访中被问到这个问题,并且无法提出我喜欢的非常好的回答。

注意:已在此处询问/回答。但我希望能得到一些更实用的细节,如下所述:

  • 如果需要能够评论或以其他方式将数据添加到重复事件的一个实例中,那将如何工作?
  • 事件更改和删除如何工作?
  • 您如何计算未来事件何时发生?
4

7 回答 7

10

我首先实现了Martin Fowler 概述的一些时间表达式。这负责确定计划项目何时实际发生。这是一种非常优雅的方式。我最终得到的只是文章中的内容。

下一个问题是弄清楚如何在世界上存储表达式。另一个问题是,当您读出表达式时,它们如何适应不太动态的用户界面?有人谈论只是将表达式序列化为 BLOB,但很难遍历表达式树以了解它的含义。

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

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

于 2009-01-15T18:31:14.583 回答
2

@Joe Van Dyk 问:“你能看看未来,看看即将举行的活动什么时候举行吗?”

如果您想查看/显示事件的下n 个发生,则必须a)提前计算并存储在某处或b)动态计算并显示。这对于任何晚间框架都是一样的。

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

调度系统不需要这些信息,它只需要知道下一个事件是什么时候。

于 2008-09-23T21:55:11.727 回答
2

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

于 2008-09-23T21:11:17.043 回答
0

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

:)

//W

于 2008-10-02T19:56:39.053 回答
0

保存事件时,我会将时间表保存到商店(我们称之为“时间表”,我会计算下一次触发事件的时间并将其保存,例如在“事件”中。然后我会查看“事件”并确定下一个事件何时发生并在此之前睡觉。

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

重复。

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

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

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

于 2008-09-23T21:01:59.903 回答
0

在我的脑海中(在打字/思考时修改了几件事之后):

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

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

每次应用程序运行时,它都会检查所有事件,将 (today/now +recurrenceResolution) 与 (recentRunTime + runInterval) 进行比较,如果它们一致,则触发事件。

于 2008-09-23T21:15:14.927 回答
0

几年前,当我为自己编写一个日历应用程序时,我基本上只是从 cron 中窃取了调度机制并将其用于重复事件。例如,除一月之外的每个月的第二个星期六发生的事情将包括指令“repeat=* 2-12 8-14 6”(每年,第 2-12 个月,第 2 周从第 8 日到第 14 日,和 6 代表星期六,因为我使用从 0 开始的星期几编号)。

虽然这可以很容易地确定事件是否在任何给定日期发生,但它无法处理“每 N 天”的重复发生,而且对于不熟悉 unix 的用户来说也不太直观。

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

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

于 2008-09-24T06:46:29.220 回答