我有一个API端点,它根据用户的请求执行操作,然后回显json响应。此端点还需要触发通知,但仅在延迟30秒后触发。原因是用户在该延迟内(通过另一个端点)反转其请求,这意味着不应发送通知。这是相关的代码:
// response
echo json_encode(
array(
'success' => 1,
'updateUser' => $updateUser['ok'],
'updateTarget' => $updateTarget['ok'],
'updateActivity' => $updateActivity['ok']
)
);
// send push notification after delay
sendDelayedNotification($user_id, $target_id);
sendDelayedNotification
函数中有sleep(30)
来延迟执行。然后,该功能检查是否仍存在保证通知的条件。
问题是即使此函数在echo
语句之后触发,它也会延迟响应并且请求超时。有没有办法对此进行编码,以便不会延迟响应?
答案 0 :(得分:1)
不要在同一个脚本中完成这项工作。你的php脚本的响应不会发送,直到整个脚本运行完毕。
您需要使用其他脚本发送通知。让您的响应设置数据库记录或使用初始请求的时间创建文件或其他内容。通知脚本将扫描位置并根据需要发送通知。您的取消端点将删除/修改记录,以便通知脚本不会执行。
答案 1 :(得分:1)
PHP本质上是同步的。
选项很少:
<强> 1st_script.php 强>
<?php
echo json_encode(
array(
'success' => 1,
'updateUser' => $updateUser['ok'],
'updateTarget' => $updateTarget['ok'],
'updateActivity' => $updateActivity['ok']
)
);
exec('php 2nd_script.php > /dev/null 2>/dev/null &');
<强> 2st_script.php 强>
<?php
sleep(30);
doStuff();
将第二个PHP脚本作为守护程序运行并使用http://supervisord.org/之类的内容来确保它不会死亡。
<强> 1st_script.php 强>
<?php
echo json_encode(
array(
'success' => 1,
'updateUser' => $updateUser['ok'],
'updateTarget' => $updateTarget['ok'],
'updateActivity' => $updateActivity['ok']
)
);
submitJobToQueue(data);
2nd_script.php - supervisord运行的脚本。
<?php
while(true) {
$job = getJobOlderThan30Sec();
executeJobQueue($job);
}
OR 2nd_script.php - crontab的脚本。
<?php
$job = getJobOlderThan30Sec();
executeJobQueue($job);
我曾与ZendQueue,Gearman和RabbitMQ合作开展大型项目。 最喜欢兔子。 Gearman有一些可扩展性问题。 ZendQueue或任何其他基于数据库的队列将是最简单的,但它不像其他人那样是推送系统。