Subscription emails can send multiple times to same user

Created on 12 January 2023, over 1 year ago
Updated 5 February 2023, over 1 year ago

Problem/Motivation

If a very large number of subscribers receive immediate email notifications, it is possible that the system will send duplicate emails to the same user. I believe this is because the module's email queuing system can place user/emails in the queue multiple times.

A modification/simplification of the system may be needed.

From what I can tell, after you publish an Announcement, cron claims the cron_announcement_builder item from the queue. The item is given an "expires" time of around 5 seconds or less.

The processing of the item is done in the group_subscription module. It queries the users that should receive the announcement and adds new cron_announcement_immediate items to the queue for each of those emails. It sometimes doesn’t finish this before the next cron run (in our site's case, that is every 5 minutes), and “releases” the item back to the queue.

When an item is “released” with a DatabaseQueue, it sets its “expires” back to 0 so that another worker knows to claim it. I think this is just what happens — and the whole process starts all over again, adding new items to the queue to send out emails.

TL;DR: Processing the first cron_announcement_builder queue item (that creates other queue items) takes too long, gets put back into the queue, and gets run again.

Steps to reproduce

This is very difficult to reproduce without a very large number of subscribers. Our site has around 10K-20K subscribers.

Proposed resolution

The process of having a queue item that generates other queue items may be too complicated — and too prone to error. Basically, the site just needs to know whether to create cron_announcement_immediate items or not. It's either a "yes" or "no."

Would it make sense to use a state variable instead? Something like:

if (\Drupal::state()->get('group_subscription.should_queue_items') {
  // Add cron_announcement_immediate items.
  ...
  \Drupal::state()->set('group_subscription.should_queue_items', FALSE);
}

(I'm sure there is some important logic I'm missing or something I've forgotten about queueing, but I hope that conveys my idea.)

🐛 Bug report
Status

Active

Version

3.0

Component

Code

Created by

🇺🇸United States majorrobot

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

Production build 0.69.0 2024