每月触发的重复自动化未按预期运行

好的,Moin 和我今天聊到了这个案例,她提到使用“每月”时可能存在一个 bug,因为月份的长度各不相同?当然,她是对的——至少部分正确::stuck_out_tongue:

不管怎样,我又做了一些调查::detective:

我实际上在核心 plugins/automation/lib/discourse_automation/scripts 文件夹中找不到 schedule pm with data-explorer results 的自动化脚本,所以它可能藏在别的地方。

但我查看了 plugins/automation/lib/discourse_automation/triggers/recurring.rb 中关于重复执行的逻辑(推测该脚本会使用它):

我认为每月重复自动化的底层代码是在计算“第 N 个星期 X”,而不是实际的日历日期,这与“日历日期”存在逻辑不匹配。也就是说,通过向 RRule 注入 BYDAY=#{count}#{byday},自动化强制按星期几对齐,而应该使用 BYMONTHDAY 而不是 BYDAY

因此,如果你将自动化设置为从 4 月 15 日开始(这一天恰好是 4 月的第三个星期三),系统会将该规则解释为:在每个月的第三个星期三运行

到了 5 月,第三个星期三是 5 月 20 日,这导致计划向后漂移了 5 天。

此外,如果你将自动化设置在某月的 30 日或 31 日(例如“第五个星期二”),系统会在下个月寻找第五个星期二。如果该月只有四个星期二,自动化将完全无法找到有效日期,并 静默跳过整个月份

我已经测试了一个修复方案,并准备提交 PR,如果团队想查看的话。它将逻辑从“第 N 个星期 X”改为精确的“日历日期”。


以下是我在测试和调试过程中的一些截图:

两个实例,一个未修复,另一个应用了我的逻辑修复。

在两者中创建完全相同的自动化(修复版本在右侧):

查看横幅中显示“下次自动化将在以下时间触发:”的差异,其中存在 5 天的漂移——未打补丁的版本漂移到了 第三个星期三(5 月 20 日),而不是 5 月 15 日。

例如,如果系统寻找的是“第四个星期四”而不是实际日期,某些月份可能会被完全跳过。

也可以在 Rails 控制台中测试相同的结果。

未打补丁的版本:

应用修复后:

PR 地址:

编辑:该 bug 似乎影响了所有使用 recurring 触发器并设置为每月运行的自动化脚本。:grimacing:

我有时也能复现空横幅的情况,例如,如果将开始日期设置为 2026 年 4 月 29 日,那么系统将无法找到 5 月的“第五个星期三”,因为该日期不存在——自动化将在此处失败(未修复版本在左侧,修复版本在右侧):

看起来当系统无法找到如上的“第 N 个星期 X”时,Rails 会抛出 NoMethodError;因此导致下次触发横幅为空,且运行失败:

2 个赞