【问题标题】:PHP Killing Old Script Execution on RetryPHP在重试时杀死旧脚本执行
【发布时间】:2014-09-14 22:31:11
【问题描述】:

好的,我已经尝试解决这个问题了 ,但没有找到解决办法。我已经询问了与我的问题有关的 4-5 个不同的问题,但没有找到解决方案。

file.phpexample1.com:

我在这个页面上有一个 JavaScript 函数,它向example2.com(一个不同的域)上的一个 PHP 文件发送一个 POST 请求。

function buttonFunction() {
    $.post("http://example2.com/core/runner.php",{username:username, password:pword, coins:coins}, function(data) {
        // Stuff
    });
}

该函数将runner.php的结果动态加载到页面的一个div中。

现在如果用户在执行过程中离开页面(结果尚未生成)然后他/她刷新页面,然后决定再次运行该函数,那么两个 PHP 进程将运行同时来自同一个用户(也就是说,如果旧用户仍在运行)。

现在我需要一个修复,无论是在example2.com 上的PHP 文件中还是在example1.com 上的JavaScript 中,都可以在开始新的请求之前中止/停止之前的PHP 请求。

我的尝试:

#1

我已经尝试过了,但不幸的是跨域 cookie 几乎是不可能的:

PHP session files saved, but no cookies and session not read

目标是将 PHP pid 存储在 SESSION 变量中,并在每次运行时检查具有该 pid 的旧进程是否仍在运行(通过从 SESSION 变量中获取 pid),如果是,那么我会杀死该进程并将 SESSION 变量的值更改为新的 pid。

#2

我还尝试运行一个循环来检查连接是否在主脚本运行时中止。但是,这也不起作用:

PHP run loop and script at same time

#3

我也想过做这样的事情:

window.onbeforeunload = function(event) {
    http.abort();
};

所以它会在用户离开/刷新页面/浏览器之前中止请求。但是,我不确定这个的可靠性 (Safe Way to Send POST Request via Javascript)。

【问题讨论】:

    标签: javascript php jquery session cookies


    【解决方案1】:

    正如其他用户所指出的,使用文件是执行此操作的最佳方式。我的逻辑是这样的:

    runner.php 运行时:

    • 先检查是否存在名为username+number的文件
    • 如果存在则删除该文件,并创建一个名为 username + (number+1) 的新文件
    • 如果不存在则创建一个名为 username+1 的文件
    • 将此数字(即 1 或数字+1)存储在变量中
    • 做任何需要的处理
    • 在发回响应之前,检查名为(用户名+您在 var 中的号码)的文件是否存在
    • 如果是,发送响应
    • 如果不是,则表示另一个(稍后)进程正在运行(仅针对该用户,因为我们用用户名命名文件)并且该进程已删除您当前进程的文件,因此直接终止而不做任何事情。

    当然,这可能不是最佳解决方案,但应该适用于您的用例。

    检查PHP中的文件功能,这不需要复杂的魔术代码。

    【讨论】:

    • 但是,假设用户有多个帐户并且在他/她的第一次尝试使用account1,但在执行过程中离开页面并使用account2 重试怎么办。在这种情况下,将运行两个 PHP 进程。
    • @user3681788 是的,但针对不同的帐户。你必须告诉我们你的脚本在做什么。
    • @raidenace 也许,但我不希望account1 的进程在等待太长时间/实际上变得无响应的情况下停留在那里并消耗服务器资源。
    • @szymanskilukasz - 我同意。我认为相同的 runner.php 将为不同的用户处理不同的数据集。在这种情况下,并行处理问题应该只存在于同一个用户调用它两次,而不是多个用户。
    • @user3681788:我认为应该是这样。 runner.php 不会为两个不同的用户处理不同的数据集吗?
    【解决方案2】:

    当你第一次执行你的脚本 runner.php 你可以创建一个文件并锁定它直到脚本结束,所以当有另一个对该脚本的请求时你可以检查文件是否被锁定 - 然后你有信息如果您可以再次运行脚本,例如:

    $fo = fopen('lock.txt', 'r+'); 
    if (flock($fo, LOCK_EX)) 
    {
        // File was not locked, You have locked it successfully right now, do your logic 
        flock($fo, LOCK_UN); // unlock file afer script logic
    } 
    else
    { 
        // File is locked right now, don't run script
    }
    

    之后,您可以向用户发送消息,他可以稍后尝试(因为第一个脚本正在运行)而不是杀死第一个脚本。

    我认为这是杀死脚本时的设计问题,看起来不太好。当你在执行过程中杀死脚本时数据呢?这可能会导致一些严重的问题。

    【讨论】:

    • 但是,我希望多个人能够同时使用它。我只希望脚本在用户离开发送 AJAX 请求的页面时停止执行。另外,脚本有时需要很长时间才能完成,甚至无法响应。因此,出于这个原因,我宁愿不加锁,而只是终止脚本的执行。
    • @user3681788 因此,您可以使用用户名创建文件以仅锁定唯一用户,或者使用一些键值存储,例如 redis 即我认为这是杀死脚本时的设计问题,它不是看起来很棒。当您在执行过程中杀死脚本时,数据呢?这可能会导致一些严重的问题。
    猜你喜欢
    • 2013-07-24
    • 1970-01-01
    • 2023-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多