предотвратить таймаут php в блоке кода

Хотел узнать, был ли способ предотвратить тайм-аут php, если часть кода начала обрабатываться.

Позволь мне объяснить:

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

ini_set('max_execution_time', 0);
set_time_limit(0);

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

$email->save();
$this->_setDoneWebsiteId($user['id'], $websiteId);

есть ли в php способ сказать, что он должен завершить их выполнение, даже если тайм-аут вызван?

Получив идею, когда я пишу это, я мог бы использовать time_out 120 секунд и запустить таймер, и если до истечения времени ожидания осталось менее 20 секунд, я просто хотел узнать, что я что-то упустил.

Спасибо за ваш вклад.

1

Решение

Если ваш код не является синхронным и некоторые задачи занимают более 100 секунд — вы не сможете проверить время выполнения.

Я вижу только один действительно HACK (будьте осторожны, проверьте его с помощью php -f в консоли, чтобы иметь возможность убивать процессы):

<?php
// Any preparations here
register_shutdown_function(function(){
if (error_get_last()) { // There was timeout exceeded error
// Call the rest of your system
// But note: you have no stack, no context, no valid previous frame - nothing!
}
});
1

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

Одна вещь, которую вы могли бы сделать, это использовать функции времени DATE для контроля вашего среднего времени выполнения. (вид создается с каждым выполнением, предполагая, что у вас есть цикл).

Если среднее тогда время будет больше, чем сколько времени у вас осталось (вы бы посчитали, сколько времени уже занято против вашего максимального времени выполнения), вы бы запустили перезапуск и позволили ему продолжить с того места, где он остановился. ,

Как бы то ни было, если вы испытываете тайм-ауты, вы, возможно, захотите найти способы сделать свой код более эффективным.

0

Нет, вы не можете прервать обработку тайм-аута, но я бы сказал, что 20 секунд — это довольно большое время, если вы не анализируете что-то огромное. Тем не менее, вы можете сделать следующее:

  • Получить время начала исполнения ($start = $_SERVER['REQUEST_TIME'] или просто $start = microtime(true); в начале вашего контроллера).
  • Предположим, что время выполнения меньше 100 секунд до запуска $email->save() или остановите / пропустите код при необходимости. Это так же просто, как if (microtime(true) - $start < 100) { $email->save()... }, Вы хотели бы больше абстракции по этому вопросу, однако.
  • (при необходимости) проверьте время выполнения после запуска обоих методов и остановите выполнение, если время истекло.

Это потребует time_limit установить большое значение или даже отключить и утомительную работу, чтобы предотвратить слишком долгое выполнение. В большинстве случаев тайм-аут — это ваш друг, который просто говорит, что ваша работа занимает слишком много времени, и вы должны переосмыслить свою архитектуру и внутренние процессы; если вам не хватает 120 секунд, вы, вероятно, захотите включить эту работу в работу демона.

0

Спасибо за ваш вклад, так как я думал, что решение по таймеру — лучший способ.

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

ini_set('max_execution_time', 180);
set_time_limit(180);

$startTime = date('U'); //give me the current timestamps

while(true){
//gather all the data i need for the email

//I know its overkill to break the loop with 1 min remaining
//but i realy dont want to take chances
if(date('U') < ($startTime+120)){
$email->save();
$this->_setDoneWebsiteId($user['id'], $websiteId);
}else{
return false
}
}

Я не мог использовать идею измерения среднего времени каждого цикла, так как оно слишком сильно варьируется.

Я мог бы сделать код более эффективным, но его количество циклов зависит от количества пользователей и веб-сайтов в рамках. Он должен вырасти настолько большим, что в любом случае потребуется многократный пробег.

Мне нужно провести некоторое исследование, чтобы понять функцию register_shutdown_function, но я посмотрю на это.

Еще раз спасибо!

0
По вопросам рекламы [email protected]