koderoff/enqueue-extra-bundle
Symfony bundle that integrates enqueue with extra message queue features. A low-adoption package with minimal documentation, best suited for experimental or internal Symfony projects rather than production use.
This bundle is a thin add-on on top of enqueue/enqueue-bundle — it does not replace it. Read the bundle class and its DI extension before anything else, because that is where the entire surface area lives:
src/Koderoff*Bundle.php — the bundle class (does it register compiler passes? a getContainerExtension?).src/DependencyInjection/*Extension.php — the config tree. This tells you exactly which keys you are allowed to set, which is the single most useful piece of documentation for a package this small.Resources/config/*.yml (or config/) — the service definitions it adds, including any tags that wire into Enqueue.composer.json — check the require block against your project. This package last shipped in May 2020, so it will be pinned to Symfony 4/5-era and enqueue/* 0.9–0.10 constraints.Minimal setup, assuming you already have enqueue/enqueue-bundle working:
composer require koderoff/enqueue-extra-bundle
// config/bundles.php
return [
// ...
Enqueue\Bundle\EnqueueBundle::class => ['all' => true],
Koderoff\EnqueueExtraBundle\KoderoffEnqueueExtraBundle::class => ['all' => true],
];
Configure a transport (e.g. AMQP or Redis) under the normal enqueue: key, then the package's own key (verify the exact name from the extension — likely enqueue_extra: or koderoff_enqueue_extra:):
# config/packages/enqueue.yaml
enqueue:
default:
transport: 'amqp://guest:guest@localhost:5672/%2f'
client: ~
Then import routes and set up the broker:
bin/console enqueue:setup-broker # or enqueue:transport:setup-amqp
bin/console debug:container | grep -i enqueue # confirm what the bundle added
First use case: pick one non-critical side effect in your app — sending a welcome email, indexing a record, pushing a webhook — and move it behind a producer/consumer pair. A controller sends an event; a worker consumes it. That gives you a realistic exercise for the package without putting critical traffic on an unmaintained dependency.
Producer in the request path, consumer in a worker. Use the Enqueue\Client\ProducerInterface service directly (or Enqueue\Client\Client if you need sendCommand for point-to-point work). Keep payloads scalar and versioned:
final class RegistrationController
{
public function __construct(private ProducerInterface $producer) {}
public function __invoke(User $user): Response
{
$this->producer->sendEvent('user.registered', [
'v' => 1,
'id' => $user->getId(),
'email' => $user->getEmail(),
]);
return new Response('', 202);
}
}
Consumer as a tagged processor. Implement Enqueue\Client\ProcessorInterface (or TopicSubscriberInterface if you want the class to declare its own topic) and let the bundle's compiler pass register it. This is where an "extra" bundle usually earns its keep — check whether it provides a base processor class, retry wrapper, or command-routing helper, and extend that rather than reinventing it.
final class SendWelcomeEmail implements ProcessorInterface
{
public function process(Message $message, Context $session): Result
{
$data = $message->getBody(); // array/json depending on serializer
// ...
return Result::ACK;
}
}
Domain-event fan-out. If the package exposes an event dispatcher bridge, route Symfony domain events to topics in one listener rather than sprinkling sendEvent across services. Keeps the queue abstraction out of your domain.
Supervisor for workers. Whatever the bundle adds, consumption still happens through bin/console enqueue:consume --env=prod. Run it under Supervisor/systemd with --time-limit=3600 and --memory-limit, and set stopwaitsecs above your longest handler.
Testing. Swap in the null or fs transport in config/packages/test/. For unit tests, mock ProducerInterface and assert on the topic name and message body — do not boot the bundle just to verify a dispatch.
Deployment. Put enqueue:setup-broker (idempotent) in your deploy script before starting workers, and ensure the transport credentials come from env vars, not the committed YAML.
composer.json and record an owner for it. Better: read the DependencyInjection/ directory, copy the 100–200 lines you actually need into your app as a small internal bundle, and drop the requirement entirely.enqueue-bundle has moved through several majors; this package's composer.json almost certainly excludes them. Expect composer update to either fail or force you onto old Enqueue versions. If you must keep it, composer why-not enqueue/enqueue-bundle first, and consider a replace/fork.Extension::load() without prepend() on the Enqueue config. If your enqueue: transport settings get clobbered, check for a PrependExtensionInterface and add the ordering yourself in your app's extension.enqueue-bundle, the default serializer wraps arrays in a Message envelope; getBody() may return a JSON string rather than an array depending on the transport. Decode defensively and version payloads ('v' => 1) so a later change to the consumer does not break in-flight messages.--time-limit so a leaky handler gets recycled, and give each message a correlation ID in the log context so you can trace a job across producer and consumer.TransportFactory registration. Those are the two legitimate hooks: a custom transport factory lets you support a broker the bundle doesn't; a processor tag lets you wrap every consumer in retry/logging/metrics decorators without touching business code.bin/console debug:container --tag=enqueue.client.processor (or the equivalent tag the bundle uses) is the fastest way to confirm your consumer registered. If a message vanishes, check the driver's route mapping — an unregistered topic silently no-ops in some drivers.How can I help you explore Laravel packages today?