如果在 APIPlatform 3.1 中的同一资源上使用处理器,Messenger 将无法工作

问题描述 投票:0回答:1

我使用的是API平台3.1。我需要在创建后生成某些实体的缩略图。我想使用 Symfony Messenger 来触发此操作并异步执行,因为可能需要一些时间来处理,但我希望立即保存实体。

当资源同时使用信使和自定义处理器(以保存实体)时,如果使用

messenger=true
,则不会创建消息,或者如果使用
messenger='input'
,则不会调用处理器。

如何重现

#[ORM\Entity]
#[ApiResource(
    operations: [
        new Post(
            processor: MyEntityProcessor::class,
            messenger: 'input',
            deserialize: false, 
        )
    ]
)]
class MyEntity
{
}
final class MyEntityProcessor implements ProcessorInterface
{
    public function __construct(private ProcessorInterface $persistProcessor)
    {
    }

    public function process($data, Operation $operation, array $uriVariables = [], array $context = [])
    {
        $result = $this->persistProcessor->process($data, $operation, $uriVariables, $context);
        return $result;
    }
}
final class MyEntityHandler implements MessageHandlerInterface
{
    public function __construct(private EntityManagerInterface $entityManager)
    {
    }

    public function __invoke(MyEntity $myEntity)
    {
        // my long running function

        $this->entityManager->persist($myEntity);
        $this->entityManager->flush();
    }
}

services.yaml

services:
    App\State\MyEntityProcessor:
        bind:
            $persistProcessor: '@api_platform.doctrine.orm.state.item_provider'

messenger.yaml

framework:
    messenger:
        transports:
            async: 'doctrine://default'

        routing:
            'App\Entity\MyEntity': async

API 平台文档在Symfony Messenger Integration中提到:

注意:在 Doctrine 实体中使用

messenger=true
ApiResource 属性时,不会调用 Doctrine 处理器。如果你希望 Doctrine Processor 被调用,你应该装饰一个内置的状态处理器并实现你自己的逻辑。

在 GitHub 问题上建议我应该装饰消息处理程序以保存实体。但是,我需要立即保存我的实体,而不是等待它被 messenger:consume

 工作人员消耗。

php symfony api-platform.com
1个回答
0
投票
您似乎遇到了 API 平台和 Symfony Messenger 集成的特定挑战,您希望使用 Symfony Messenger 触发异步缩略图生成,同时确保立即保存实体。由于处理器、信使和实体保存之间的交互,这可能有点棘手。这是您可以考虑的一种潜在方法:

  1. 解耦实体创建和缩略图生成: 不要直接从实体创建过程触发缩略图生成,而是考虑将其解耦。创建实体后,立即保存实体并使用 Symfony Messenger 发送一条消息,指示需要为新创建的实体生成缩略图。

  2. 使用消息处理程序生成缩略图: 创建一个单独的消息处理程序,用于侦听实体创建过程分派的缩略图生成消息。该处理程序应负责生成缩略图并使用生成的缩略图信息更新实体。它还可以在更新实体后立即持久化和刷新实体。

  3. 实体处理:MyEntityProcessor

     类中,仅专注于处理实体并避免处理缩略图生成逻辑。这样,您可以保持关注点分离并保持逻辑清晰。

以下是组件如何交互的高级概述:

    创建
  • MyEntity
     实例后,
    MyEntityProcessor
     会立即保存它来处理它。
  • 一条消息被发送到 Symfony Messenger,指示需要为新创建的实体生成缩略图。
  • MyEntityHandler
    消息处理程序接收消息,生成缩略图,更新实体,然后立即保留并将实体刷新到数据库。
通过以这种方式构建应用程序,您可以实现实体的立即保存,同时仍然利用 Symfony Messenger 进行异步缩略图生成。

请记住在

messenger.yaml

 中正确配置消息处理程序和路由,以确保缩略图生成消息由适当的消息处理程序处理 (
MyEntityHandler
)。

此方法需要对代码进行一些重组,但应该可以帮助您实现使用 Symfony Messenger 和 API 平台立即保存实体和异步缩略图生成的目标。

© www.soinside.com 2019 - 2024. All rights reserved.