Я пытаюсь ограничить количество писем, отправленных с моего сайта, чтобы справиться с ограничениями электронной почты для хостинга. Я использую задания cron и индикатор сложения электронных писем в базе данных, чтобы проверить, приближается ли количество отправленных писем к максимальному количеству отправленных сообщений.
То, как я это делаю, заключается в прямом выполнении запланированного процесса, затем делает его "спящим" в течение определенного периода времени (в соответствии с его положением в очереди), а затем отправляет электронное письмо и регистрируется в базе данных. Чтобы далее объяснить причину, по которой я использую запланированные задачи и "спать", рассмотрим следующий сценарий:
- Пользователь пытается зарегистрироваться на моем сайте и ожидает, что в ближайшее время ему будет отправлено электронное письмо. Таким образом, если превышена квитанция электронной почты/минут, мне нужно отправить другое сообщение: "Наш сервер занят, пожалуйста, разрешите" x "минуты выполнить требуемую задачу".
- Запросы на отправку электронной почты выполняются через AJAX. Использование "сна" внутри самого процесса не является вариантом, потому что пользователю придется ждать минут x до тех пор, пока не появится сообщение "занято".
- Я пытался с ob_flush, flush... и т.д. комбинации для эха сообщения, а сервер работает в фоновом режиме, но это никогда не срабатывало. Вызов AJAX всегда ожидал завершения script для эхо-результата.
-
Мне нужно многопоточность на однопоточном языке PHP! В качестве обходного пути я использовал задания cron, где каждая сложенная электронная почта планируется выполнить в
time()
(т.е. Непосредственно запустить запланированное задание), которая подключена к той же функции, которая отправляет электронные письма. Используя флаг, функция знает, что запрос является сложенным электронным письмом и делает его "спящим" до времени, необходимого для квоты электронной почты reset. -
Проблема: если 5 человек зарегистрированы почти в одно и то же время (в то время как у нас все еще есть куча электронной почты), тогда у нас есть 5 заданий cron, которые должны выполняться одновременно, а затем спать некоторое время ( время сна может отличаться, если количество писем в куче уже больше, чем квота по электронной почте), затем отправляются электронные письма. Однако, когда я проверяю журналы в базе данных, я обнаруживаю, что запланированные задания выполняются последовательно, а не параллельно. Иногда бывает, что задание cron запускается до других целей, но они не срабатывают одновременно.
Я знаю, что задания wordpress cron не являются заданиями cron и увольняются, когда кто-то посещает веб-сайт (и я уверен, что обновляю страницы после отправки запросов на регистрацию для запуска всех запланированных задач), но они, похоже, быть единственным вариантом для меня, так как мой хостинг-сервер не разрешает доступ к серверу, не позволяет планировать задания cron.
Вот часть кода, который выполняет вышеуказанное:
//Test example to pile up emails, where quota is set to 2 emails every 30 seconds
$Emails_Threshold = 2;
$Threshold_Duration = 0.5*60;
//Get email indicator info
$Email_Info = $wpdb->get_row(
"SELECT *
FROM PileEmails
WHERE priority = -1
AND Status='New';"
,ARRAY_A);
if ($sleep ==0 && $Queue_Info_id==0){ //Not a scheduled event
//Check if there are queued emails
$Queue_exist = $wpdb->get_row (
$wpdb->prepare("
SELECT Status
FROM PileEmails
WHERE Status='Queued';"
,$mail_priority)
,ARRAY_A);
if (!empty($Queue_exist) || ($Email_Info['last_email_time'] > (time()-$Threshold_Duration))){
if ($Email_Info['count_emails']>=$Emails_Threshold){
//Code to Pile up
}
}else{
//Reset email counter
}
}else{
$wpdb->insert( "PileEmails",$Sleep_Info,$format);
sleep(10); //10 seconds here just as an example
}
//Code to send emails
Вот что я регистрирую в базе данных, когда пытаюсь отправить 10 писем после превышения квоты.
Обратите внимание, что временная метка имеет разницу в 10 секунд между каждым журналом и следующим, хотя все они должны быть запущены одновременно и каждый спящий в течение 10 секунд, после чего все отправляют письма параллельно.
Итак, мой вопрос: почему wordpress cron запускает запланированные задания последовательно, а не параллельно? и как преодолеть эту проблему?
Любая помощь очень ценится.