Хотел узнать, был ли способ предотвратить тайм-аут php, если часть кода начала обрабатываться.
Позволь мне объяснить:
у меня есть скрипт, который выполняется слишком долго, чтобы даже использовать
ini_set('max_execution_time', 0);
set_time_limit(0);
код построен так, чтобы он мог тайм-аут и перезапустить, где он был, но у меня есть 2 строки кода, которые должны быть выполнены вместе, чтобы это произошло
$email->save();
$this->_setDoneWebsiteId($user['id'], $websiteId);
есть ли в php способ сказать, что он должен завершить их выполнение, даже если тайм-аут вызван?
Получив идею, когда я пишу это, я мог бы использовать time_out 120 секунд и запустить таймер, и если до истечения времени ожидания осталось менее 20 секунд, я просто хотел узнать, что я что-то упустил.
Спасибо за ваш вклад.
Если ваш код не является синхронным и некоторые задачи занимают более 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!
}
});
Одна вещь, которую вы могли бы сделать, это использовать функции времени DATE для контроля вашего среднего времени выполнения. (вид создается с каждым выполнением, предполагая, что у вас есть цикл).
Если среднее тогда время будет больше, чем сколько времени у вас осталось (вы бы посчитали, сколько времени уже занято против вашего максимального времени выполнения), вы бы запустили перезапуск и позволили ему продолжить с того места, где он остановился. ,
Как бы то ни было, если вы испытываете тайм-ауты, вы, возможно, захотите найти способы сделать свой код более эффективным.
Нет, вы не можете прервать обработку тайм-аута, но я бы сказал, что 20 секунд — это довольно большое время, если вы не анализируете что-то огромное. Тем не менее, вы можете сделать следующее:
$start = $_SERVER['REQUEST_TIME']
или просто $start = microtime(true);
в начале вашего контроллера).$email->save()
или остановите / пропустите код при необходимости. Это так же просто, как if (microtime(true) - $start < 100) { $email->save()... }
, Вы хотели бы больше абстракции по этому вопросу, однако.Это потребует time_limit
установить большое значение или даже отключить и утомительную работу, чтобы предотвратить слишком долгое выполнение. В большинстве случаев тайм-аут — это ваш друг, который просто говорит, что ваша работа занимает слишком много времени, и вы должны переосмыслить свою архитектуру и внутренние процессы; если вам не хватает 120 секунд, вы, вероятно, захотите включить эту работу в работу демона.
Спасибо за ваш вклад, так как я думал, что решение по таймеру — лучший способ.
в итоге я сделал следующее: это не код, так как он слишком длинный, чтобы дать хороший ответ, а просто общая идея.
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, но я посмотрю на это.
Еще раз спасибо!