Lilly
(Lillian )
13
好的,Moin 和我今天聊到了这个案例,她提到使用“每月”时可能存在一个 bug,因为月份的长度各不相同?当然,她是对的——至少部分正确:
不管怎样,我又做了一些调查:
我实际上在核心 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 触发器并设置为每月运行的自动化脚本。
我有时也能复现空横幅的情况,例如,如果将开始日期设置为 2026 年 4 月 29 日,那么系统将无法找到 5 月的“第五个星期三”,因为该日期不存在——自动化将在此处失败(未修复版本在左侧,修复版本在右侧):
看起来当系统无法找到如上的“第 N 个星期 X”时,Rails 会抛出 NoMethodError;因此导致下次触发横幅为空,且运行失败:
2 个赞