代码之家  ›  专栏  ›  技术社区  ›  Joe Van Dyk

设计问题:如何设计一个重复事件系统?[关闭]

  •  46
  • Joe Van Dyk  · 技术社区  · 16 年前

    如果您受命构建一个支持重复事件的事件调度系统,您会怎么做?移除定期事件时如何处理?你怎么知道将来的事情什么时候会发生?

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

    请每个回复一个设计。我已经习惯了ruby/rails,但是不管你想表达什么样的设计。

    在一次采访中,有人问我这个问题,但我没能给出一个我喜欢的很好的回答。

    注:是 already asked/answered here. 但我希望得到一些更实际的细节,具体如下:

    • 如果有必要对重复事件的一个实例进行注释或以其他方式添加数据,这将如何工作?
    • 事件更改和删除将如何工作?
    • 你如何计算未来事件发生的时间?
    7 回复  |  直到 16 年前
        1
  •  10
  •   oglester    16 年前

    我首先实现了一些时态表达式 outlined by Martin Fowler . 这需要弄清楚计划的项目应该在什么时候实际发生。这是一种非常优雅的做法。我最终得到的只是在文章内容的基础上的一个积累。

    下一个问题是如何在世界上存储表达式。另一个问题是,当您读出表达式时,这些表达式如何适应一个不那么动态的用户界面?有人说只是将表达式序列化成一个blob,但是要遍历表达式树来知道它的含义是很困难的。

    解决方案(在我的例子中)是存储符合用户界面将支持的有限数量情况的参数,然后从那里开始,使用这些信息动态地生成时态表达式(在创建用于优化时可以序列化)。因此,schedule类最终有几个参数,比如offset、start date、end date、day of week等等……从中你可以生成时间表达式来完成这项艰巨的工作。

    至于任务的实例,有一个“服务”生成n天的任务。因为这是与现有系统的集成,并且需要所有实例,所以这是有意义的。但是,这样的api可以很容易地用于投影重复,而不必存储所有实例。

        2
  •  2
  •   Joe Phillips    16 年前

    我以前在管理项目的数据库端时不得不这样做。我要求将每个事件存储为单独的事件。这允许您只删除一个事件,也可以移动范围。删除倍数比尝试修改一个匹配项并将其转换为两个要容易得多。然后,我们可以制作另一个表,其中只包含一个recurrenceid,其中包含复发的信息。

        3
  •  2
  •   henriksen    16 年前

    @乔范戴克问:“你能不能展望未来,看看即将到来的事件是什么时候?”

    如果你想的话 显示/显示 下一个 n 事件的发生他们必须 a) 提前计算并存储在某处或 b) 实时计算并显示。这对于任何晚上的框架都是一样的。

    a)的缺点是你必须在某个地方对它进行限制,之后你必须使用b)。一开始就很容易使用b)。

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

        4
  •  0
  •   henriksen    16 年前

    保存事件时,我会将计划保存到商店(我们称之为“ 时间表 我会计算事件下次何时触发并保存它,例如 事件 “。那我就进去看看” 事件 “弄清楚下一个活动是什么时候,然后睡觉,直到那时。

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

    重复。

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

    如果应用程序正在启动或从睡眠事件或类似事件中恢复,请检查“ 事件 “对于已通过的事件,并相应地采取行动(取决于您希望如何处理错过的事件)。

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

        5
  •  0
  •   clweeks    16 年前

    从我的头顶(在打字/思考时修改了一些东西之后):

    确定所需的最小重复解决方案;这是应用程序运行的频率。也许是每天,也许每五分钟。

    对于每个重复发生的事件,存储最新的运行时间、运行间隔和其他一些有用的东西,如到期时间(如果需要)。

    每次运行应用程序时,它都会检查所有事件,并将(today/now+recurrenceresolution)与(recentruntime+runinterval)进行比较,如果两者一致,则触发该事件。

        6
  •  0
  •   Dave Sherohman    16 年前

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

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

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

    我不认为这是最好的办法,但是 是的,而且在我前面提到的限制范围内工作得很好。

        7
  •  0
  •   Wiren    16 年前

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

    :)

    //W