无法执行异步操作/命令

时间:2021-04-14 21:01:51

标签: php symfony

我有一个 symfony 应用程序,我需要在其中异步发送电子邮件。当我的用户执行某些操作时,我需要向管理员发送电子邮件。为此,我创建了一个 symfony 自定义命令以与 Symfony Process Component 一起使用,它类似于 php native 的 exec()。我的代码如下:

    if ($trigger == true) {
        $command = 'php bin/console async-email';
        $process = new Process([$command]);
        $process->start();
        $pid = $process->getPid();
    }

根据官方文档,这应该足够了,但我可以确认没有发送电子邮件。但是,当我威胁要等待命令结束(如非异步)并打印结果时,命令完美运行并且电子邮件被发送。

        $process->wait(function ($type, $buffer) use ($data) {
        // do stuff
        });

        return new JsonResponse([$process->getErrorOutput(), $process->getOutput(), $pid]);

我也试过:

  • 用里面的命令创建了一个批处理文件。
  • 在进程内运行自定义 php 脚本。

任何方法都有效,但不是异步的。我需要的是命令在后台执行操作而不干扰正常的代码执行。

2 个答案:

答案 0 :(得分:1)

首先,如果你从主进程开始一些异步进程,你需要等到所有的异步进程完成后才结束主进程。在其他情况下,当主进程关闭时,所有异步子进程在结束任务之前都会被杀死。这是任何应用的一般规则。

因此,如果您不想等待发送的电子邮件,请将邮件添加到队列中,然后完成主请求。然后从 php bin/console async-email 即每 5 分钟运行一次 corn。这将是异步的。

但是恕我直言,如果用户在执行某些(不是每个)操作后发送单个电子邮件,那么从控制器操作同步发送这封电子邮件是完全没问题的。

答案 1 :(得分:0)

您对 symfony 进程组件行为 100% 正确@Łukasz Jakubek。您可以运行 n 个异步子进程(彼此之间),但它们依赖于主进程,因此如果您不等待或检查完成,它们会在主执行结束时被终止。

我还没有完全理解异步和背景之间的区别。因此,在 Julien B 提出上述建议之后,我意识到我需要一个队列系统,所以我花了最后 12 个小时重构我的代码以使用 symfony messenger 与学说传输和voilá,效果很好!

将来可能需要寻找更先进的队列系统,例如允许动态异步队列的 RabbitMQ。

现在我的问题已经解决,更重要的是我的方向是正确的,非常感谢!