Prevent duplication of unsent scheduled reminders #31600
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Overview
This PR provides a fix for the issue identified and discussed in https://lab.civicrm.org/dev/core/-/issues/3824. In the original issue, a server misconfiguration caused the sending of scheduled reminders to fail partway through. This resulted in multiple copies of the same reminder being queued up for sending every time the job ran (even if the reminder was already queued to send), meaning that when the job eventually succeeded, thousands of duplicate reminders were sent to contacts in the database.
Before
When sending a scheduled reminder on a repetition schedule, there is no mechanism to check whether a previous instance of the reminder was already queued to send but never actually got sent. As such, every time the job runs, a new copy of the reminder is queued to send. If and when the emails are actually sent, you get duplicate reminders.
See issue linked above for further details and screenshots etc.
Also, as a side issue, if the repetition schedule is set to 'minutes', this is incorrectly interpreted as 'hours'.
After
When sending a scheduled reminder on a repetition schedule, we now check to make sure that no previous unsent copies exist. If there are, we leave those to be sent but do not queue up a new copy of the reminder to be sent, thus avoiding duplication.
Also, the code to interpret 'minutes' as a schedule interval option is added.
Technical Details
The linked issue includes details of the testing used to simulate the problem and prove that it can be contained by this fix, and to prove that the fix does not interfere with normal sending of reminders.
In addition to this, the proposed fix has been live for > 1 month on a production system running CiviCRM 5.78.3. Reminders have been observed to continue sending as normal.
Comments
This is a robustness improvement to prevent a highly undesirable cascade failure mode (sending many hundreds or thousands of emails to users) in the event of a fault.