Миллионы писем вставляются в таблицу MySQL «EmailQueue» со следующими полями:
Обычно строки будут вставлены со статусом «Ожидание», но некоторые сообщения с высоким приоритетом, такие как «Забыть / Сбросить пароль», будут вставлены с «Приоритет» в столбце статуса.
Задание cron будет запускаться каждый час и отправлять письма в виде цикла с пакетом из 20000 писем в каждом цикле, пока оно не завершит отправку всех сообщений. Теперь я хочу сначала отправить приоритетные письма, которые можно добавить в очередь электронной почты, даже когда выполняется задание cron.
Каков наилучший подход для достижения этого? Я не уверен, стоит ли задавать этот вопрос stackoverflow, но не уверен насчет лучшего места. Спасибо за любую помощь заранее.
Если мы игнорируем «добавить, пока 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
}
}
Это вопрос использования правильного запроса, например, если вы знаете, что задание будет запускаться каждое электронное письмо, пока очередь не будет исчерпана:
SELECT *
FROM EmailQueue
WHERE status IN ('Pending','Prioritized')
ORDER BY status DESC, created_datetime ASC
LIMIT 0,100;
В результате каждый раз, когда вы запускаете запрос, вы сначала получаете приоритетные электронные письма, а затем ожидающие электронные письма, оба из которых упорядочены самыми старыми.
Вы можете запускать этот пакет сколько угодно раз, пока очередь не будет исчерпана или максимум 200 раз в час, чтобы соответствовать пределу в 20000 часов.
Я предполагаю, что когда вы начинаете обработку, вы меняете статус на Processing
и когда вы закончите, вы измените статус на Processed
, Вот почему вы всегда начинаете с 0, а не с добавочного числа.