我已经在网站上为一个客户端提供了一个功能,该服务器从实时服务器获取数据以在本地保存它,但我没想到的是有时这些本地服务器不在某个区域中良好的服务,所以在一段时间后脚本会不时因为无法连接而死亡。
我已经实施了一个系统来禁用针对这些类型情况的外部呼叫,但是客户端无法选择设置此类"离线模式"首先,因为服务很糟糕,服务器正试图访问实时服务器。
所以我需要做的是将SyncTable
函数包含在set_time_limit(8)
之类的函数中,该函数调用另一个函数来设置"离线模式"如果SyncTable
功能在8秒内无法完成,则自动执行。
这样的事情可能吗?如果是这样,我很想知道如何在服务粗糙的地区为这些客户节省一些时间。
答案 0 :(得分:0)
您可以使用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;
}