设计问题:我们将如何设计重复事件系统?

时间:2020-03-06 14:37:36  来源:igfitidea点击:

如果我们负责构建支持重复事件的事件计划系统,我们将如何做?重复发生的事件被删除后,我们该如何处理?我们如何看待未来的事件何时发生?

即创建事件时,我们可以选择"每天重复"(或者每周,每年等)。

请为每个回应提供一种设计。我已经习惯了Ruby / Rails,但是使用任何我们想要表达的设计。

面试中有人问我这个问题,但无法提出我喜欢的非常好的答复。

注意:此处已被要求/回答。但我希望获得一些更实际的细节,如下所示:

  • 如果有必要能够对重复事件的一个实例进行注释或者以其他方式添加数据,那么它将如何工作?
  • 事件更改和删除将如何工作?
  • 我们如何计算未来事件的发生时间?

解决方案

保存事件时,我会将日程表保存到商店中(我们将其命名为" Schedules",然后我会计算该事件下次触发的时间并将其保存,例如保存在" Events"中。然后,我会查看"事件",找出下一个事件何时发生并入睡。

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

重复。

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

如果应用正在启动或者从睡眠事件或者类似事件中恢复,请检查"事件"中已传递的事件并采取相应的措施(取决于我们要对丢失的事件进行的处理)。

这样的事情将很灵活,并且不会占用不必要的CPU周期。

在管理项目的数据库末尾之前,我必须这样做。我要求将每个事件存储为单独的事件。这使我们仅可以删除一个事件,也可以移动跨度。删除倍数要比尝试修改单个事件并将其变成两个要容易得多。然后,我们可以制作另一个表,该表仅具有recurrenceID,其中包含重复信息。

离开我的头顶(在打字/思考时修改了几件事):

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

对于每个重复发生的事件,如果需要的话,请存储最近的运行时间,运行间隔和其他有效期,例如到期时间。

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

@乔·范戴克(Joe Van Dyk)问:"你能不能展望未来,看看即将发生的事件何时发生?"

如果要查看/显示事件的下n个事件,则必须a)预先计算并存储在某个地方,或者b)快速计算并显示。对于任何晚上的框架来说都是一样的。

a)的缺点是我们必须在某处对其进行限制,然后再使用b)。只需使用b)即可开始。

调度系统不需要此信息,它只需要知道下一个事件何时发生即可。

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

尽管这样可以很容易地确定事件是否在任何给定的日期发生,但是它不能处理"每隔N天"的重复发生,并且对于不懂unix的用户来说还不够直观。

为了处理单个事件实例和删除/重新安排的唯一数据,我只是跟踪了事件的计算距离,并将结果事件存储在数据库中,然后可以在其中对其进行修改,移动或者删除而不会影响原始周期性事件信息。添加新的重复事件时,将立即计算出所有实例,直到现有的"上次计算"日期为止。

我没有断言这是最好的方法,但是它是一种方法,并且在我前面提到的限制内效果很好。

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

:)

// W

我首先实现了马丁·福勒(Martin Fowler)概述的一些时间表达。这有助于弄清楚何时应该实际发生计划项目。这是一种非常优雅的方法。我最终得到的只是文章内容的基础。

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

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

至于有任务的实例,有一项"服务"可以生成N天的任务。由于这是对现有系统的集成,并且需要所有实例,所以这很有意义。但是,这样的API可以很容易地用于投影循环,而无需存储所有实例。