我有一个 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]);
我也试过:
任何方法都有效,但不是异步的。我需要的是命令在后台执行操作而不干扰正常的代码执行。
答案 0 :(得分:1)
首先,如果你从主进程开始一些异步进程,你需要等到所有的异步进程完成后才结束主进程。在其他情况下,当主进程关闭时,所有异步子进程在结束任务之前都会被杀死。这是任何应用的一般规则。
因此,如果您不想等待发送的电子邮件,请将邮件添加到队列中,然后完成主请求。然后从 php bin/console async-email
即每 5 分钟运行一次 corn
。这将是异步的。
但是恕我直言,如果用户在执行某些(不是每个)操作后发送单个电子邮件,那么从控制器操作同步发送这封电子邮件是完全没问题的。
答案 1 :(得分:0)
您对 symfony 进程组件行为 100% 正确@Łukasz Jakubek。您可以运行 n 个异步子进程(彼此之间),但它们依赖于主进程,因此如果您不等待或检查完成,它们会在主执行结束时被终止。
我还没有完全理解异步和背景之间的区别。因此,在 Julien B 提出上述建议之后,我意识到我需要一个队列系统,所以我花了最后 12 个小时重构我的代码以使用 symfony messenger 与学说传输和voilá,效果很好!
将来可能需要寻找更先进的队列系统,例如允许动态异步队列的 RabbitMQ。
现在我的问题已经解决,更重要的是我的方向是正确的,非常感谢!