У меня уже есть функция на веб-сайте для клиента, который захватывает данные с живого сервера, чтобы сохранить его локально, но я не ожидал, что иногда эти локальные серверы не находятся в зоне с хорошим сервисом, поэтому каждый сейчас и то скрипт умирает через определенное время, потому что он не смог подключиться.
У меня уже есть система, предназначенная для отключения внешних вызовов для этих типов ситуаций, но клиенты не могут перейти к настройке этого "автономного режима", потому что служба плохая, и сервер пытается достичь живого сервер.
Так что мне нужно сделать, это обернуть мою функцию SyncTable
с помощью функции, такой как set_time_limit(8)
которая вызывает другую функцию, которая автоматически устанавливает "автономный режим", если функция SyncTable
не завершится за 8 секунд.
Что-то вроде этого возможно? Если это так, я хотел бы знать, как я могу спасти этих клиентов некоторое время в районах с грубым обслуживанием.
Вы можете выполнить это с помощью proc_open, proc_get_status и proc_terminate, чтобы запустить операцию SyncTable в качестве процесса, контролировать его и, при необходимости, прервать его. Примечание. Возможно, вам понадобится создать простой скрипт-оболочку, чтобы вы могли запустить функцию SyncTable как отдельный процесс.
Вот функция, которую я использую для этого и применяю тайм-аут:
/// Executes a command and returns the output
/// If the timeout value (in seconds) is reached, it terminates the process
/// and returns FALSE
function exec_timeout($cmd, $timeout=30)
{
$descriptors = array(
0 => array('pipe', 'r'), // stdin
1 => array('pipe', 'w'), // stdout
2 => array('pipe', 'w') // stderr
);
$pipes = Array();
$process = proc_open($cmd, $descriptors, $pipes);
$result = '';
$end_time = time() + $timeout;
if (is_resource($process))
{
// set the streams to non-blocking
stream_set_blocking($pipes[0], 0);
stream_set_blocking($pipes[1], 0);
stream_set_blocking($pipes[2], 0);
$timeleft = $end_time - time();
while ($timeleft > 0)
{
$status = proc_get_status($process);
$result .= stream_get_contents($pipes[1]);
// leave the loop if the process has already finished
if (!$status['running'])
break;
$timeleft = $end_time - time();
}
if ($timeleft <= 0)
{
proc_terminate($process);
$result = FALSE;
}
}
// check for errors
$errors = stream_get_contents($pipes[2]);
if (!empty($errors))
fwrite(STDERR, "$errors\n");
// close streams
fclose($pipes[0]);
fclose($pipes[1]);
fclose($pipes[2]);
proc_close($process);
return $result;
}