Асинхронність

Асинхронність

JsonRpcBundle приймає RPC-запити не лише по HTTP. Ті самі методи можна викликати через черги повідомлень Symfony Messenger, а частину роботи навіть у синхронних запитах сервер виконує поза основним потоком.

Асинхронність у синхронних запитах

  • Batch-запити у процесному режимі виконують елементи паралельно в дочірніх процесах.
  • Notifications і запити з $rpc.callback виконуються після відправлення відповіді клієнту.

Асинхронний транспорт (Symfony Messenger)

Транспорти оголошуються списком у блоці async налаштувань:

# config/packages/ufo_json_rpc.yaml
ufo_json_rpc:
    async:
        - type: 'amqp'
          config:
              name: 'rpc_async'
              dsn: '%env(resolve:RPC_TRANSPORT_DSN)%'

Елементи з type: amqp реєструються як транспорти Symfony Messenger: name стає назвою транспорту, і повідомлення RpcAsyncRequest маршрутизуються на нього (або на config.route, якщо задано). DSN може вказувати на будь-який транспорт, який підтримує Messenger.

Щоб запустити RPC сервер як споживача черги, виконайте:

php bin/console messenger:consume rpc_async

Споживач перевіряє токен і виконує метод. Генеруються події виконання (rpc.pre_execute, rpc.pre_response, rpc.post_execute, rpc.error), але не rpc.request і rpc.post_response — див. Життєвий цикл. Помилки токена й невідомого методу стають помилками обробки повідомлення Messenger (повторні спроби, failure transport).

Відправка запиту в чергу

use Symfony\Component\Messenger\MessageBusInterface;
use Ufo\RpcObject\RpcAsyncRequest;

$bus->dispatch(new RpcAsyncRequest($rpcRequest, $token, apiGroup: 'internal'));

apiGroup визначає групу API; без нього використовується general. Токен перевіряється тим самим валідатором, що й для HTTP.

Інші типи транспортів

Елементи з іншим type (наприклад, mercure) бандл до Messenger не підключає. Вони доступні застосунку через RpcAsyncConfig::getConfig(<type>) і, якщо docs.async_dsn_info: true, публікуються в документації (x-ufo.transport) під своїм name.

ufo_json_rpc:
    async:
        - type: 'mercure'
          config:
              name: 'rpc_socket'
              dsn: '%env(resolve:MERCURE_PUBLIC_URL)%'
              topics_prefix: 'rpc.event.'

Транспорт для невдалих повідомлень (failure transport) оголошуйте в framework.messenger самостійно — ключ failed у конфігурації бандла не підтримується з версії 9.1.

Переваги асинхронного транспорту

  1. Масштабованість: навантаження розподіляється між кількома споживачами.
  2. Надійність: брокер (RabbitMQ тощо) гарантує доставку повідомлень.
  3. Єдиний API: ті самі методи, валідація й безпека, що й для HTTP.