停止请求服务器端

时间:2014-01-17 19:21:14

标签: php ajax apache unix

我有一个名称查找框,可以按照典型的ajax请求进行操作。这是每次按下一个字母时触发的Javascript的一般流程:

  • 如果ajax请求已经打开,则中止它。
  • 如果已经创建了超时,请将其销毁。
  • 设置新超时以在半秒内运行以下内容:
  • 通过ajax
  • 将字符串发送到'nameLookup.php'
  • 等待回复
  • 显示结果

问题是nameLookup.php资源非常庞大。在某些情况下,从SQL数据库中提取多达10,000个名称,解密并与字符串进行比较。在正常情况下,请求可能需要5到60秒才能返回。

我完全理解当你在客户端中止请求时,服务器仍在处理事情并发回结果。只是客户端知道忽略响应。但是服务器正忙着处理所有这些请求。

所以,如果你这样做:

  • 请求1
  • 中止请求1
  • 请求2
  • 中止请求2
  • 要求3
  • 等待来自Request 3的回复

服务器要么甚至没有处理请求3,直到它完成了1和2 ...或者它只是挂起来处理请求1和2,请求3需要花费更长的时间。

我需要知道如何告诉服务器停止处理请求1和2,这样我就可以腾出资源让它在Request 3上工作。

我正在使用Javascript&客户端的jQuery。服务器端的PHP / Apache和SQL。

3 个答案:

答案 0 :(得分:0)

  1. 在表格或会话中的DB中存储布尔值。
  2. 让您的资源密集型脚本定期检查该值,以确定它是否应该继续。如果数据库说要停止,那么您的脚本会自行取消(例如,通过调用当前函数中的return;)。
  3. 如果您想要取消,而不是调用abort();,请发出一个AJAX请求,将该值设置为false
  4. 下次资源检查该值时,它会看到它必须停止。
  5. 潜在的限制:  1.您的脚本无法定期检查数据库。  2.根据脚本检查数据库的频率,可能需要几秒钟才能有效地终止脚本。

答案 1 :(得分:0)

我认为这个问题缺少一些内容。触发请求的触发因素是什么?您可能正在尝试解决错误的问题。

让我详细说明一下。如果您的查找框实际上在进行某种自动补全,并且每次用户按下某个键时都在进行新的搜索,那么您将遇到您描述的问题。

那种情况下的解决方案不是杀死所有进程。解决方案在于不启动它们。因此,您可能会做出一些决定,例如,如果只搜索一个字符,则不尝试搜索-假设我们选择了三个。然后,我们可能会说我们要等到可以合理确定用户完成输入后再发送请求。可以说我们等待一秒钟。

现在,在您的姓名列表中查找所有Paul的人将在键入“ pau”并暂停1秒钟时发送一次搜索,而不是先搜索“ p”然后“ pa”再“ pau”,再搜索3次。 ..因此无需杀死任何东西。

答案 2 :(得分:-2)

我已经提出了一个很棒的解决方案,我已经测试过并且它工作得非常好。只需几行PHP代码就可以放入任何资源密集的文件中。

此解决方案使用服务器中的Process Identifier (PID)。我们可以使用两个PHP函数:posix_getpid()来获取当前的PID,使用posix_kill()来杀死另一个PID。这也假设你已经在其他地方调用了session_start()。

以下是代码:

//if any existing PIDs to kill, go through each
if ($_SESSION['pid']) foreach ($_SESSION['pid'] as $i => $pid) {

    //if posix_kill returns true, unset this PID from the session so we don't waste time killing it again
    if(posix_kill($pid,0)) unset($_SESSION['pid'][$i]);

}

//now that all others are killed, we can store the current PID in the session
$_SESSION['pid'][]=posix_getpid();

//close the session now, otherwise the PID we just added won't actually be saved to the session until the process ends.
session_write_close();

要注意事项:

posix_kill有两个值。第一个是pid,第二个应该是来自this list的信号常数之一。没有什么对我有任何意义,其他人似乎只使用0成功,当我使用0时它返回true。无论如何工作!

在资源密集型事情开始发生之前调用session_write_close()至关重要。否则,在页面的所有处理完成之前,已保存到会话的新PID将不会实际保存到会话中。这意味着下一个过程将无法取消那个仍在进行并永远消失的过程。