PHPackages                             sbooker/command-bus - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. sbooker/command-bus

ActiveLibrary

sbooker/command-bus
===================

Command bus

1.1.0(1y ago)16.1k11MITPHPPHP ^7.4 || ^8.0

Since Jun 4Pushed 8mo ago1 watchersCompare

[ Source](https://github.com/sbooker/command-bus)[ Packagist](https://packagist.org/packages/sbooker/command-bus)[ RSS](/packages/sbooker-command-bus/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (5)Dependencies (14)Versions (15)Used By (1)

[Read in English](README.EN.MD)

Asynchronous Command Bus (`sbooker/command-bus`)
================================================

[](#asynchronous-command-bus-sbookercommand-bus)

[![Latest Version](https://camo.githubusercontent.com/69fd65cc737b0b8786584c9d02b2b14c322e8e94245e7c5ccd3f62e014f7489d/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f73626f6f6b65722f636f6d6d616e642d6275732e7376673f7374796c653d666c61742d737175617265)](https://img.shields.io/packagist/v/sbooker/command-bus)[![Software License](https://camo.githubusercontent.com/55c0218c8f8009f06ad4ddae837ddd05301481fcf0dff8e0ed9dadda8780713e/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d627269676874677265656e2e7376673f7374796c653d666c61742d737175617265)](https://github.com/sbooker/command-bus/blob/master/LICENSE)[![PHP Version](https://camo.githubusercontent.com/e5be4f7c6371e5d9432ef176500257ee7ec197f6a8e58f3c46ab91939ad9d1ff/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f7068702d762f73626f6f6b65722f636f6d6d616e642d6275732e7376673f7374796c653d666c61742d737175617265)](https://php.net)[![Total Downloads](https://camo.githubusercontent.com/8c2c395f2b93550e7b7c371c27d4cfeb5a95d1f297372e0db26e75adcadd4bdc/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f73626f6f6b65722f636f6d6d616e642d6275732e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/sbooker/command-bus)

Надежная, транзакционная, персистентная шина для асинхронного выполнения команд с поддержкой повторных попыток и отслеживанием состояния.

Назначение библиотеки
---------------------

[](#назначение-библиотеки)

Эта библиотека решает две ключевые задачи в современных приложениях:

**1. Надежное асинхронное выполнение задач.**Библиотека позволяет **атомарно сохранить команду** на выполнение долгой или ненадежной операции (отправка email, запрос к API) в базу данных. Отдельный фоновый процесс (воркер) гарантированно выполнит эту команду позже.

**2. Создание фундамента для отказоустойчивых Process Managers (Sagas).**В event driven системах обработка доменных событий может быть хрупкой. Например, если подписчик на событие OrderPaid пытается выполнить операцию Warehouse::reserve() и получает ошибку, вся очередь обработки событий может быть заблокирована. Выход — сделать обработку событий простой и безошибочной, преобразуя событие или последовательность событий в команду(ы). Обычно для этого используют паттерн **Process Manager (Saga)**. **Ответственность за преобразование события в команду лежит на вашем коде** (в подписчике на события). Сама библиотека **не реализует** паттерн Process Manager, но **существенно облегчает его реализацию**, предоставляя **надежный, транзакционный механизм для асинхронного выполнения этой команды**, изолируя сбои и не блокируя обработку других событий.

Ключевые особенности
--------------------

[](#ключевые-особенности)

- **Основа для Process Manager / Saga:** Предоставляет надежный механизм выполнения команд, который является ключевой частью реализации Process Manager.
- **Транзакционная надежность:** Прием команды происходит атомарно благодаря интеграции с [sbooker/transaction-manager](https://github.com/sbooker/transaction-manager).
- **Декларативные стратегии ретраев:** Логика повторных попыток не находится в обработчике. Она **декларативно настраивается для каждой команды** через `TimeoutCalculator`. Сама персистентная сущность `Command` отслеживает количество попыток и время следующего запуска. Воркер лишь пытается выполнить готовые к запуску команды.
- **Гарантированное выполнение (At-Least-Once):** Команда будет выполняться до тех пор, пока не завершится успешно или не исчерпает все попытки.
- **Отслеживание состояния:** В любой момент можно узнать статус команды (`created`, `pending`, `success`, `fail`).
- **Хуки на результат:** Определяйте колбэки (`Invoker`) на успешное или неуспешное завершение.

Установка
---------

[](#установка)

```
composer require sbooker/command-bus
```

Вам также понадобятся зависимости из экосистемы и адаптеры:

```
composer require sbooker/transaction-manager sbooker/workflow sbooker/event-loop-worker
composer require sbooker/doctrine-transaction-handler # Если вы используете Doctrine
```

Быстрый старт
-------------

[](#быстрый-старт)

### Сценарий 1: Асинхронное выполнение задачи

[](#сценарий-1-асинхронное-выполнение-задачи)

**Задача:** Отправить приветственный email, не заставляя пользователя ждать.

**1. Команда и ее Endpoint:**

```
// src/Mailing/Command/SendEmail.php
final class SendEmail { /* ... DTO с to, subject, body ... */ }

// src/Mailing/Endpoint/SendEmailEndpoint.php
use Sbooker\CommandBus\Endpoint;
final class SendEmailEndpoint implements Endpoint
{
    private Mailer $mailer;
    public function process(UuidInterface $id, object $payload): void
    {
        /** @var SendEmail $payload */
        $this->mailer->send(/* ... */);
    }
}
```

**2. Отправка команды:**

```
// src/UseCase/RegisterUser/Handler.php
/** @var Sbooker\CommandBus\CommandBus $commandBus */

$command = new SendEmail('welcome@user.com', 'Welcome!', '...');
$commandBus->accept(Uuid::uuid4(), $command); // Быстро и надежно
```

### Сценарий 2 (Продвинутый): Построение Process Manager

[](#сценарий-2-продвинутый-построение-process-manager)

**Задача:** После оплаты заказа (`OrderPaid` event) надежно зарезервировать товары на складе.

**1. Команда и ее Endpoint:**

```
// src/Warehouse/Command/ReserveItems.php
final class ReserveItems { /* ... DTO с orderId, items ... */ }

// src/Warehouse/Endpoint/ReserveItemsEndpoint.php
use Sbooker\CommandBus\Endpoint;
final class ReserveItemsEndpoint implements Endpoint
{
    private WarehouseService $warehouseService;
    public function process(UuidInterface $id, object $payload): void
    {
        /** @var ReserveItems $payload */
        $this->warehouseService->reserve(/* ... */); // Может выбросить исключение
    }
}
```

**2. Подписчик на событие (Process Manager):**

```
// src/Order/Subscriber/OrderPaidSubscriber.php
use Sbooker\DomainEvents\DomainEventSubscriber;
use Sbooker\CommandBus\CommandBus;

final class OrderPaidSubscriber implements DomainEventSubscriber
{
    private CommandBus $commandBus;
    public function handleEvent(DomainEvent $event): void
    {
        if (!$event instanceof OrderPaid) return;
        $command = new ReserveItems($event->getOrderId(), $event->getItems());
        $this->commandBus->accept(Uuid::uuid4(), $command);
    }
    // ...
}
```

### Общие шаги: Конфигурация и запуск воркера

[](#общие-шаги-конфигурация-и-запуск-воркера)

Независимо от сценария, вам нужно настроить `Registry` и запустить воркер.

**1. Конфигурация Registry:**

```
// bootstrap.php или ваш DI-контейнер
use Sbooker\CommandBus\Registry\Containerized\ContainerizedRegistry;
use Sbooker\CommandBus\Registry\Containerized\ContainerAdapter;

/** @var Psr\Container\ContainerInterface $container */

$endpointsMap = new ContainerAdapter($container, null, [
    'send-email' => SendEmailEndpoint::class,
    'reserve-items' => ReserveItemsEndpoint::class,
]);
$timeoutsMap = new ContainerAdapter($container, 'default_timeout');
$registry = new ContainerizedRegistry($endpointsMap, $timeoutsMap);
```

**2. Запуск воркера:**

```
// worker.php
/** @var Sbooker\CommandBus\Handler $handler */
while (true) {
    if (!$handler->handleNext()) sleep(5);
}
// Рекомендуется использовать sbooker/event-loop-worker для более эффективной реализации
```

**3. Настройка Doctrine:**Вам нужно предоставить маппинг для сущности `Sbooker\CommandBus\Command` и ее `embeddables`, а также зарегистрировать кастомный тип для `Status`. Или использовать [поставляемые с библиотекой](./src/Infrastructure/Persistence/Mapping)

**4. Так же в комплекте:**

- Консольная команда для ручного запуска обработки команды по ее идентификатору [ExecuteCommand](./src/Infrastructure/Console/ExecuteCommand.php)
- Консольная команда для очистки отработанных команд [Clean](./src/Infrastructure/Console/Clean.php)

License
-------

[](#license)

See [LICENSE](https://github.com/sbooker/command-bus/blob/master/LICENSE) file.

###  Health Score

40

—

FairBetter than 88% of packages

Maintenance47

Moderate activity, may be stable

Popularity20

Limited adoption so far

Community10

Small or concentrated contributor base

Maturity68

Established project with proven stability

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~124 days

Recently: every ~259 days

Total

13

Last Release

687d ago

Major Versions

0.9.0 → 1.0.02024-06-30

PHP version history (3 changes)0.2.0PHP ^7.4

0.1.0PHP ^7.2

0.4.0PHP ^7.4 || ^8.0

### Community

Maintainers

![](https://www.gravatar.com/avatar/f97b1f6ea03776dda6e0ec26d1ff3a3309972d65bd1376eb111c2b35017af339?d=identicon)[sbooker](/maintainers/sbooker)

---

Top Contributors

[![sbooker](https://avatars.githubusercontent.com/u/3658174?v=4)](https://github.com/sbooker "sbooker (19 commits)")

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/sbooker-command-bus/health.svg)

```
[![Health](https://phpackages.com/badges/sbooker-command-bus/health.svg)](https://phpackages.com/packages/sbooker-command-bus)
```

###  Alternatives

[sylius/sylius

E-Commerce platform for PHP, based on Symfony framework.

8.4k5.6M651](/packages/sylius-sylius)[shopware/platform

The Shopware e-commerce core

3.3k1.5M3](/packages/shopware-platform)[api-platform/core

Build a fully-featured hypermedia or GraphQL API in minutes!

2.6k48.1M236](/packages/api-platform-core)[shopware/core

Shopware platform is the core for all Shopware ecommerce products.

595.2M386](/packages/shopware-core)[api-platform/symfony

Symfony API Platform integration

323.2M67](/packages/api-platform-symfony)[api-platform/serializer

API Platform core Serializer

223.4M31](/packages/api-platform-serializer)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
