【问题标题】:Run function immidiately after REST-API is hit命中 REST-API 后立即运行函数
【发布时间】:2021-06-20 05:49:51
【问题描述】:

有这两种应用:

  • 带有 REST-API 的 WordPress 站点。我们称之为Brandon
  • 另一个系统,使用 REST-API。我们称之为 Jeremy

我知道 WordPress Stack Exchange,但这更像是一个 PHP 问题,而不是一个 WordPress 问题(我认为)。


问题

Jeremy 在 Brandon 上创建和更新“原子”。

每当 Jeremy 更新 Brandon 上的一个原子时,紧接着就会运行一个名为 BuildMolecules() 的操作,将原子分组并更新 Brandon 上分子的电子、中子和质子信息。

但目前,这是在 Jeremy 的帖子上完成的。这意味着如果 Jeremy 更新了一个原子,那么它必须等待 BuildMolecules() 完成,然后才能返回其响应。更糟糕的是,如果出现问题,而 BuildMolecules() 运行时,Jeremy 会收到一个错误,这是错误的(因为原子已按应有的方式更新)。最后这件事可以而且应该用 try/catch 语句来解决,但仍然......

如何在 Jeremy 更新原子后立即运行一个函数,而不在 Jeremy 的线程上执行?


解决方案尝试和注意事项

CRON 作业

我考虑过每 5-10 秒运行一次 cron-job,检查原子是否已更新。如果是这样,则运行更新操作。感觉有点调皮,因为我必须经常运行它,才能实现 Jeremy 和 Brandon 之间的顺利整合。但这应该有效。如果运行时间超过 5-10 秒,那么我将不得不考虑这一点,设置状态或其他东西,停止 BuildMolecules() 运行两次,而它应该只运行一次。

新话题

即使我可以设置一个新线程(我从未做过类似的事情),我也可以在这里阅读这篇文章:Creating new thread(?) in PHP 我不应该尝试这样做。

如果 WordPress 为其提供功能

我查看了WordPress' REST-documentation,但找不到任何可以帮助我的东西。

【问题讨论】:

    标签: php wordpress cron try-catch wordpress-rest-api


    【解决方案1】:

    一套简单的触发机制会有帮助吗?

    Jeremy 更新了一个 atom -> 这会触发一个发送给 Brandon 的请求到 BuildMolecule(),在不需要等待响应的 curl 请求中发送。该请求有一个callback 参数

    $url = 'https://brandon.com/buildMolecule.php';
    $curl = curl_init();                
    $post['callback'] = 'https://jeremy.com/onBuiltMolecule.php'; 
    curl_setopt($curl, CURLOPT_URL, $url);
    curl_setopt ($curl, CURLOPT_POST, TRUE);
    curl_setopt ($curl, CURLOPT_POSTFIELDS, $post); 
    curl_setopt($curl, CURLOPT_TIMEOUT, 1); 
    curl_setopt($curl, CURLOPT_HEADER, 0);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($curl, CURLOPT_FORBID_REUSE, true);
    curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 1);
    curl_setopt($curl, CURLOPT_DNS_CACHE_TIMEOUT, 10); 
    curl_setopt($curl, CURLOPT_FRESH_CONNECT, true);
    curl_exec($curl);   
    curl_close($curl); 
    

    Brandon 的机器运行 BuildMolecule() 但知道获取 $_POST['callback']

    function onCompleteBuildMolecule($moleculeDataArray) {
        $url = $_POST['callback'];
        $curl = curl_init();                
        $post['data'] = $moleculeDataArray; 
        // the rest same as above's cURL 
    

    如果整个设置过于简陋,您还可以使用亚马逊的 SNS service(它为相同类型的交互提供了更强大的包装器)

    【讨论】:

      【解决方案2】:

      如果这是使用像 Laravel 这样的 MVC 框架,我会使用消息队列。如果您需要在 WordPress 的上下文中执行此操作,这是一个更棘手的问题,但并非无法克服。

      PHP 中有独立的消息队列实现,例如 Bernard 和 php-enqueue,可以满足您的需求,但您确实希望使用 Composer 来安装它们,这在 WordPress 上下文中可能会很困难(尽管可能- Bedrock 是使用 Composer 的 WordPress 样板的一个示例)。或者这可能是矫枉过正 - 您可以使用 Redis 或 RabbitMQ 在较低级别实现它,或者只是用于排队作业的数据库表。

      无论你选择如何实现它,原理都是一样的——在 WordPress 中,你在收到请求时所做的只是将你需要的最少数据推送到队列后端。您有一个单独的工作进程正在运行,它会获取数据并进行处理。如果不方便,worker 不一定必须使用 PHP,它只需要能够与您的后端进行通信,如果您不将其用作队列后端,还可能与您的主应用程序数据库进行通信。

      【讨论】:

      • 这基本上是我们在 WordPress 网站中所做的。 Composer + WordPress 工作得非常好,你甚至不需要担心用它构建的主题,你只需要vendor/autoload.php。就我个人而言,我可能也将其移至插件中,只是为了分离关注点,但实际上并没有对错之分。后台工作进程是关键,我 100% 同意。您可以使用服务、循环或任何其他跑步者。
      【解决方案3】:

      这取决于您调用 REST API 的方式。

      涉及 JavaScript 吗?如果是这样,您可以发送原子修改请求而不调用构建分子 完成后,但只是响应确定。收到此“ok”后,您可以发送后台 ajax 请求来重建分子。

      如果这是一个服务器到服务器的关系,其中 JavaScript 不可用,您可以在数据库中设置分子需要重建的设置,并在常规 cron 作业中执行此操作。

      最后你可以通过系统函数使用 PHP CLI。

      <?php 
      system("nohup php -f /path/to/rebuild_molecules.php >/dev/null 2>&1 &");
      

      PHP 将开始执行rebuild_molecules 脚本,但不会等待完成。

      https://linux.die.net/man/1/nohup

      编辑: 如果你使用 PHPFPM 你也可以使用fastcgi_finish_request

      echo 'ok';
      fastcgi_finish_request();
      do_build_molecules();
      

      https://www.php.net/manual/en/function.fastcgi-finish-request.php

      【讨论】:

        【解决方案4】:

        如果您想快速解决它,而不需要构建大量基础架构,并且您使用的是 Linux,则可以使用以下内容:

        exec(PHP_BINDIR . "/php /var/www/html/your_php_file.php yourParameter > /dev/null &");
        

        您也可以通过访问 $argv 来传递 CLI 参数并在您的 php 文件中读取它们

        传递变量参数时,请使用escapeshellcmd() 转义变量。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-08-07
          • 2019-04-07
          • 2021-08-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-06-23
          • 1970-01-01
          相关资源
          最近更新 更多