Каков наилучший способ отправки приоритетных писем в очереди электронной почты?

Миллионы писем вставляются в таблицу MySQL «EmailQueue» со следующими полями:

  1. id — BigInt (20)
  2. адрес электронной почты — Varchar (300)
  3. текст сообщения
  4. status — enum («Ожидание», «Приоритет», «Обработка», «Обработано»)
  5. create_datetime — datetime
  6. sent_datetime — datetime

Обычно строки будут вставлены со статусом «Ожидание», но некоторые сообщения с высоким приоритетом, такие как «Забыть / Сбросить пароль», будут вставлены с «Приоритет» в столбце статуса.

Задание cron будет запускаться каждый час и отправлять письма в виде цикла с пакетом из 20000 писем в каждом цикле, пока оно не завершит отправку всех сообщений. Теперь я хочу сначала отправить приоритетные письма, которые можно добавить в очередь электронной почты, даже когда выполняется задание cron.

Каков наилучший подход для достижения этого? Я не уверен, стоит ли задавать этот вопрос stackoverflow, но не уверен насчет лучшего места. Спасибо за любую помощь заранее.

-1

Решение

Если мы игнорируем «добавить, пока cron работает» в течение секунды, сначала будет выбран «Приоритет»:

ORDER BY FIELD(status, "Prioritized"), id ASC

Это отсортирует все строки, где status = Prioritized, а затем упорядочит по id. Больше информации / примеры здесь.


Добавляя их в то время как cron работает сложнее, это становится логическим испытанием. Если вы делаете SELECT * FROM emails ORDER BY FIELD(status, "Prioritized"), id ASC Вы выбираете данные в данных во время выбора. Если элементы добавляются после выполнения запроса, он не будет в возвращенном наборе данных.

Чтобы получить то, что вы хотите, вам нужно разбить код на меньшие выделения:

$continueProcesss = false;
$current = 0;
$itemsPerBatch = 25;
while( $continueProcesss ){
$query = "SELECT * FROM emails ORDER BY FIELD(status, 'Prioritized'), id ASC`
LIMIT $current,$itemsPerBatch";
$result = yourQueryMethod($query);
if( $result->num_rows===0 ){
$continueProcesss = false;
break;
} else{
$current += $itemsPerBatch; // next round, we skip another $itemsPerBatch rows
}
}
1

Другие решения

Это вопрос использования правильного запроса, например, если вы знаете, что задание будет запускаться каждое электронное письмо, пока очередь не будет исчерпана:

SELECT *
FROM EmailQueue
WHERE status IN ('Pending','Prioritized')
ORDER BY status DESC, created_datetime ASC
LIMIT 0,100;

В результате каждый раз, когда вы запускаете запрос, вы сначала получаете приоритетные электронные письма, а затем ожидающие электронные письма, оба из которых упорядочены самыми старыми.

Вы можете запускать этот пакет сколько угодно раз, пока очередь не будет исчерпана или максимум 200 раз в час, чтобы соответствовать пределу в 20000 часов.

Я предполагаю, что когда вы начинаете обработку, вы меняете статус на Processing и когда вы закончите, вы измените статус на Processed, Вот почему вы всегда начинаете с 0, а не с добавочного числа.

0

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector