Skip to content
CAI
Software that uses CAICheck a score

php-service-bus/service-bus

65.4

Adequate · 22 September 2026

5.2k

lines of production code

PHP

primary language

7

measurements over time

CAI band scale
CAI trend line
CAI lens gauges

What this system is

This system is a PHP-based Service Bus framework designed to manage asynchronous message processing and event-driven architectures. It provides a modular infrastructure for routing, delivering, and executing messages through a configurable pipeline that supports automatic handler discovery, retry strategies, and structured logging. The framework abstracts away low-level transport and serialization details, allowing developers to define message handlers via PHP attributes and configure delivery options declaratively.

How it got here

2017–2018 — Service Bus refactoring and modernization

20 changes.

The codebase underwent a major refactoring to transition from a legacy event-sourcing and Symfony-based architecture to a modern PHP Service Bus implementation. This involved removing obsolete domain and infrastructure classes, updating dependencies to PHP 8.1 and Symfony 6.0, and introducing new features like attribute-based handler configuration, message execution timeouts, and improved endpoint routing.

2019 — Service bus architecture and logging

12 changes.

This period focused on establishing the core service bus architecture by implementing automatic message handler registration and dependency injection through new compiler passes and container builders. The work also introduced structured context management, granular exception handling, and configurable logging infrastructure with support for Graylog and standard output.

2020–2021 — Service Bus implementation and test coverage

8 changes.

This period focused on implementing the Service Bus architecture, introducing PHP attributes for message handling configuration, and establishing a robust retry mechanism with failed message storage. Extensive test coverage was added across the endpoint, application, and infrastructure layers to validate these new features.

Features

Add MessagesRouterConfigurator for service-based message routing

A new MessagesRouterConfigurator class has been added to the Services layer. This component iterates through a list of registered services, extracts their message handlers, and registers them with the message router as either command handlers or listeners, enabling automatic discovery and routing of messages based on service definitions.

src/Services · high confidence

Add PHP attributes for command and event handling configuration

Introduced new PHP attributes to configure message handling behavior. The \CommandHandler\ attribute now supports setting a description, enabling validation, and configuring execution timeouts via the \WithCancellation\ option. The \EventListener\ attribute allows setting a description and enabling validation. Both attributes use new option classes (\WithValidation\, \WithCancellation\) to encapsulate configuration parameters, providing a structured way to define message metadata and execution constraints.

src/Services/Attributes · high confidence

Add colorized console logging for standard output

A new logging handler and formatter have been introduced for the standard output (StdOut) to support colorized log messages. The \StdOutFormatter\ applies ANSI color codes to log levels and channel names, making console output more readable, while the \StdOutHandler\ writes formatted log records to the standard output stream.

src/Infrastructure/Logger/Handlers/StdOut · high confidence

Add environment management and configuration validation exceptions

Introduced a new \Environment\ class that allows the application to manage and validate runtime environments (production, development, testing) with methods to check the current state. Additionally, added a \ConfigurationCheckFailed\ exception class to handle specific configuration errors, such as missing entry point names, root directory paths, or environment keys.

src · high confidence

Added Graylog UDP logging handler and formatter

Users can now send log messages to a Graylog server via UDP. This change introduces a new \UdpHandler\ and \Formatter\ in the \src/Infrastructure/Logger/Handlers/Graylog\ directory, enabling structured log transmission to a specified host and port, with optional gzip compression and configurable log levels.

src/Infrastructure/Logger/Handlers/Graylog · high confidence

Added SimpleRetryCompilerPass for retry strategy configuration

A new compiler pass, SimpleRetryCompilerPass, has been introduced to configure the SimpleRetryStrategy. This component registers the retry strategy with the dependency injection container, injecting the maximum retry count and retry delay parameters, and ensures the required storage module is present.

src/Application/DependencyInjection/Compiler/Retry · high confidence

Added compiler passes to configure Monolog-based logging for Graylog and standard output

The application now includes new compiler passes to configure logging infrastructure. A new \GraylogLoggerCompilerPass\ registers a UDP handler for sending logs to a Graylog server, while \StdOutLoggerCompilerPass\ configures a handler for standard output logging. Both passes integrate with the existing \LoggerCompilerPass\, which sets up Monolog with standard processors (PsrLogMessageProcessor, MemoryUsageProcessor, ProcessIdProcessor) and ensures the active logger is not a NullLogger. This change introduces the capability to route logs to Graylog or stdout via container compilation.

src/Application/DependencyInjection/Compiler/Logger · high confidence

Added context and delivery options factories

Introduced new context-related classes in the ServiceBus library: a \ContextFactory\ interface and its \KernelContextFactory\ implementation, alongside \KernelContext\ and \DeliveryMessageMetadata\ classes. These additions provide a structured way to create and manage service bus contexts, enabling message routing and delivery through a factory pattern that integrates with the existing endpoint routing and delivery options systems.

src/Context · high confidence

Added message execution timeout and validation support

The message execution pipeline now supports configurable execution timeouts and message validation. A new \TimeLimitedExecutor\ wraps handlers to enforce a maximum processing duration, logging errors if a timeout occurs. Additionally, a \MessageValidationExecutor\ validates incoming messages before execution, binding any validation failures to the service bus context. These capabilities are wired into the \DefaultMessageExecutorFactory\, which conditionally applies these wrappers based on handler options.

src/MessageExecutor · high confidence

Added new infrastructure watchers for memory and event loop monitoring

Users can now benefit from automated memory management and event loop monitoring through the new GarbageCollectorWatcher and LoopBlockWatcher components. The GarbageCollectorWatcher periodically forces garbage collection and logs memory usage, while the LoopBlockWatcher detects and logs blocking in the event loop, aiding in performance debugging and stability.

src/Infrastructure/Watchers · high confidence

Added retry mechanism for operations

Introduced a new retry mechanism for operations, allowing transient failures to be automatically retried. The \OperationRetryWrapper\ class wraps an operation and uses the \Kelunik/Retry\ library to handle repetitions based on configurable \RetryOptions\ (defaulting to 5 attempts with a 2000ms delay). This provides a standardized way to handle errors in the infrastructure layer.

src/Infrastructure/Retry · high confidence

Added retry strategies and failed message storage schema

Introduced two new retry strategies for the Service Bus: NullRetryStrategy, which logs a debug message and takes no action, and SimpleRetryStrategy, which implements a configurable retry mechanism with a fixed delay. SimpleRetryStrategy attempts to resend failed messages up to a specified maximum count, logging each attempt. If the maximum retry count is exceeded, the message is serialized, compressed, and stored in a new 'failed\_messages' database table. This table, defined by a new SQL schema file, includes columns for message metadata, payload, and failure context, with indexes on message hash, message ID, and recorded timestamp to support future recovery processes.

src/Retry · high confidence

Automatic message handler registration via compiler passes

The application now automatically discovers and registers message handlers (commands and event listeners) through two new Symfony compiler passes: \ImportMessageHandlersCompilerPass\ and \TaggedMessageHandlersCompilerPass\. The first pass scans configured directories for PHP files containing \\#\[CommandHandler\]\ or \\#\[EventListener\]\ attributes, excluding specific files, and registers them with the \service\_bus.service\ tag. The second pass collects all tagged services, resolves their dependencies via reflection, and builds a service locator map (\service\_bus.services\_map\) to facilitate dependency injection for handlers. This enables automatic wiring of handlers without manual service configuration.

src/Application/DependencyInjection/Compiler · high confidence

Introduce ContainerBuilder for Symfony DI container compilation

Added a new ContainerBuilder class in the ServiceBus application layer to manage the compilation and caching of the Symfony dependency injection container. This component allows registering compiler passes, extensions, and modules, and provides methods to build and retrieve the cached container instance, supporting the framework's modular architecture.

src/Application/DependencyInjection/ContainerBuilder · high confidence

Introduce new entry point processing architecture

Added new classes for handling incoming messages and managing the application's entry point. The \EntryPoint\ class now manages concurrent task execution, queue listening, and graceful shutdown, while \DefaultEntryPointProcessor\ handles message decoding, routing, and execution with retry strategies. A new \IncomingMessageDecoder\ manages decoder selection based on message metadata, and \ReceivedMessageMetadata\ provides a concrete implementation of message metadata. These changes replace the previous entry point implementation, introducing a more robust and configurable message processing pipeline.

src/EntryPoint · high confidence

Introduced DefaultDeliveryOptions and associated factories for message delivery configuration

Added a new \DefaultDeliveryOptions\ class and corresponding factory classes (\DefaultDeliveryOptionsFactory\ and \DeliveryOptionsFactory\ interface) in the \src/Endpoint/Options\ directory. These components allow users to configure message delivery options such as persistence, mandatory routing, immediate delivery, and expiration. The previous \EventInterface\ and \ServiceInterface\ in the domain layer have been refactored into these new endpoint-specific options, enabling more granular control over how messages are handled by the service bus.

src/Endpoint/Options · high confidence

Introduced attribute-based service handler configuration

The configuration layer now supports loading message handlers via PHP 8+ attributes (CommandHandler, EventListener) instead of relying on legacy interfaces or annotations. A new \AttributeServiceHandlersLoader\ reads method-level attributes to build handler metadata, while \DefaultHandlerOptions\ and \ServiceMessageHandler\ provide structured configuration for validation, cancellation, and descriptions. This change enables declarative handler registration directly on service methods.

src/Services/Configuration · high confidence

New endpoint delivery and routing infrastructure

The src/Endpoint directory now contains a complete set of new classes that define how messages are encoded, routed, and delivered. DeliveryPackage bundles a message with its delivery options and metadata. The Endpoint interface specifies the contract for sending single or bulk messages. EndpointEncoder handles message serialization using a configurable ObjectSerializer. EndpointRouter manages outbound message routing by mapping message classes to specific endpoints, with support for global fallback endpoints. MessageDeliveryEndpoint implements the Endpoint interface, handling the actual transport of messages with retry logic and header management. This change introduces the core components for outbound message delivery in the service bus.

src/Endpoint · high confidence

Removals

Removal of Symfony-based message serialization implementation

The \SymfonyMessageSerializer\ class, which previously handled message serialization and deserialization using the Symfony Serializer component, has been removed from the \src/Infrastructure/Serializer\ directory. This change eliminates the specific implementation that relied on Symfony's PropertyComponent and Serializer for converting messages to and from JSON, indicating a shift away from this particular serialization strategy within the concurrency framework's infrastructure layer.

src/Infrastructure/Serializer · high confidence

Behavioural changes

Application bootstrap and kernel initialization refactored

The application entry point has been restructured with the introduction of a new \Bootstrap\ class that handles environment loading and container compilation, while the \ServiceBusKernel\ now manages transport and entry point execution. Additionally, the \ServiceBusExtension\ has been moved from the common logger handlers to the application's dependency injection extensions, shifting the framework's initialization flow to be more modular and aligned with Symfony's DI conventions.

src/Application · medium confidence

New alerting infrastructure for sending notifications

The alerting subsystem has been refactored to support sending alerts via multiple providers. A new \AlertContext\ class allows messages to be highlighted or directed to specific topics. The \AlertingProvider\ interface and \ChainAlertingProvider\ implementation enable chaining multiple notification services. A \TelegramAlertingProvider\ has been added to send messages to Telegram channels, with logic to skip sending in debug environments. The \AlertMessage\ class, previously named \EventSourcedEntryRestoredEvent\, now carries templated content for alerts.

src/Infrastructure/Alerting · high confidence

New exception classes for service bus validation errors

Added three new exception classes to the service bus library to handle specific error conditions: InvalidEventType for invalid event types, InvalidHandlerArguments for invalid handler arguments (including static methods for empty or invalid first arguments), and UnableCreateClosure for closure creation failures. These exceptions provide more granular error handling for the publish-subscribe pattern implementation.

src/Services/Exceptions · high confidence

Removal of common utility and formatting classes

The \ThrowableFormatter\, \LoggerRegistry\, \JsonSerializeHandler\, \ObjectUtils\, and \ReflectionUtils\ classes in the \src/Common\ directory have been removed. This eliminates the framework's built-in mechanisms for formatting exception strings, managing named logger channels, serializing data to/from JSON, and performing reflection-based object introspection.

src/Common · high confidence

Removal of core Domain layer classes

A significant number of classes from the \src/Domain\ directory have been removed, including the \DateTime\ helper, the \Environment\ configuration class, and the \DomainEvent\ and \DomainEventStream\ structures. The removal also eliminates interfaces and implementations for the message bus, saga state management, event sourcing, and pipeline processing. This change strips out the foundational domain abstractions and data transfer objects that previously supported event sourcing and message handling within the framework.

src/Domain · high confidence

Removal of legacy saga implementation and state management

The legacy saga infrastructure has been removed from the codebase. Specifically, the \AbstractSaga\ base class, the \SagaState\ class, and the saga contract event classes (\SagaFailedEvent\, \SagaInitializedEvent\) have all been deleted. This eliminates the previous implementation of saga lifecycle management and state tracking within the event sourcing layer.

src/Infrastructure/EventSourcing/Saga · high confidence

Removed event-sourcing repository implementations

The \AggregateRepository\ and \SagaRepository\ classes in the \src/Infrastructure/EventSourcing/Repository\ directory have been deleted. These classes previously handled the loading and saving of aggregate roots and saga instances via an event store, effectively removing the default persistence layer for event-sourced entities from the infrastructure.

src/Infrastructure/EventSourcing/Repository · high confidence

Removed legacy Event Sourcing base classes and contracts

The abstract base class \AbstractEventSourced\, the \AbstractAggregateRoot\ class, and the \EventSourcedEntryCreatedEvent\ contract have been removed from the \src/Infrastructure/EventSourcing\ directory. This eliminates the previous implementation of the event-sourced entry and aggregate root patterns, likely as part of a broader refactoring or migration of the event sourcing infrastructure.

src/Infrastructure/EventSourcing · high confidence

Removed legacy event storage implementations and configuration

The in-memory and PostgreSQL event storage backends, along with their associated configuration classes (StorageAuth, StorageHost, StorageConfigurationConfig, StorageConnectionDsnParser) and the StorageFactory, have been removed from the codebase. This eliminates the previous storage abstraction layer, paving the way for the new Doctrine2 integration.

src/Infrastructure/EventSourcing/Storage · high confidence

Updated test and code quality configuration files

The project's test and static analysis configuration has been updated. The legacy \phpunit.xml.dist\ file was removed and replaced with a new \phpunit.xml\ that configures test suites for multiple internal components (common, annotations-reader, cache, http-client, message-serializer, messages-router, mutex, storage, transport, telegram-bot-core) and sets environment variables for Redis, NSQ, and PostgreSQL. Additionally, new configuration files were added for PHPStan (\phpstan.neon\), Psalm (\psalm.xml\), and PHP-CS-Fixer (\.php-cs-fixer.dist.php\) to enforce code standards and type checking. The \.gitignore\ file was also updated to track coverage reports.

(repo-wide) · high confidence

Test coverage

Added integration tests for the Service Bus Kernel; Added test coverage for infrastructure components; Added test infrastructure for the Service Bus endpoint layer; Added test stubs for application bootstrap; Added tests for the Service Bus entry point and attribute handling; Added tests for the application bootstrap process; Added unit tests for ContainerBuilder; Added unit tests for environment, logger, and test context; Added unit tests for the Graylog log formatter; Added unit tests for the message handler compiler pass.

Dependencies

Upgrade to PHP Service Bus v5.1 and Symfony v6.0

The project has been rebranded from 'desperado/concurrency-framework' to 'php-service-bus/service-bus', reflecting a shift in focus towards a PHP Service Bus implementation. The minimum supported PHP version has been raised to 8.1, and the codebase has been updated to use the \ServiceBus\ namespace. Dependencies have been significantly updated: the project now relies on \php-service-bus\ components (http-client, common, transport, storage, etc.) at version 5.1, and several Symfony components (dependency-injection, config, dotenv, yaml, validator, error-handler) have been upgraded to version 6.0. Additionally, development tools like PHPUnit, Psalm, and PHPStan have been updated to their latest compatible versions.

(dependencies) · high confidence

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

How this codebase got here

This is the PUBLIC form of this artifact. Findings are listed in full, but the details of SECURITY findings — which rule fired, in which file, on which line, and how to fix it — are deliberately withheld, and any secret-scanner results are excluded entirely. Where detail is absent here it was REMOVED FOR PUBLICATION; it is not missing from the analysis. The complete artifact is available from the repository owner.

Score

  • CAI 63 → 65 (+2.9)
  • Rubric changed (rubric-2026.08.19 → rubric-2026.09.15) — scores are not directly comparable.

Lenses

  • Code Health 100 → 100 (+0.0)
  • Architecture 100 → 86 (-13.8)
  • Maturity 54 → 54 (+0.0)
  • Readiness 68 → 60 (-7.3)
  • Security 57 → 93 (+35.8)

Resolved (16)

  • Coverage not included — suite not readable by the collector
  • Dependency hygiene not measured — dependency manifest found but not parsed for hygiene
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • No exposed public API
  • Test reliability not included
  • dormant codebase — no living knowledge left to concentrate

New (22)

  • Ambiguous naming for environment configuration methods. 'withDotEnv' implies loading from a .env file, while 'withEnvironmentValues' is vague about the source (could be env vars, could be a file, could be hardcoded). They likely serve similar purposes (configuring the environment context) but with different inputs.
  • Change coupling: DefaultMessageExecutor.php ↔ MessageValidationExecutor.php (src/MessageExecutor/DefaultMessageExecutor.php)
  • Dependency hygiene PARTLY measured — Composer dependencies read, no committed lock to grade for currency
  • Documentation: no installation or build instructions (README.md)
  • Documentation: no usage examples (README.md)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • Inconsistent builder pattern return types and intent. 'create()' returns a new instance (static factory style), while 'nonPersistent()' and 'withHeader()' return 'self' (instance builder style). This forces users to choose between a static factory or an instance builder, but mixing them requires knowing which method returns 'self' vs a new instance. Specifically, 'create()' is a static factory, while others are instance mutators.
  • Medium: security finding (details withheld)
  • No dependency advisory monitoring
  • …and 2 more

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

Survey your own repository

php-service-bus/service-bus was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.

About this page

  • The score is its most recent published measurement, taken on 22 September 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
  • Measured at commit c87360077ba42aef48d42c99d0be99803b8df58f — the exact code this score is about.
  • Scored under rubric-2026.09.15 — the same rubric and the same method as every other entry in this index.
  • Measured by watchdog.canine.dev using codehealth-analyzer preprod-821afab8930d.