splash/tasking-bundle
A Symfony bundle that adds a lightweight tasking layer to your application, helping you define, organize, and run reusable tasks through a clean PHP API while keeping task logic out of controllers and services.
Reality check first. This bundle has 1 star, 0 dependents, and its last release was 2020-09-29. That combination means there is effectively no community knowledge base, no Stack Overflow corpus, and no downstream projects to crib patterns from. Treat your first hour as code archaeology, not documentation reading.
Install and register.
composer require splash/tasking-bundle
Then register it the Symfony way — in config/bundles.php:
return [
// ...
Splash\TaskingBundle\SplashTaskingBundle::class => ['all' => true],
];
If the class name doesn't resolve, list what the package actually shipped:
composer show splash/tasking-bundle
ls vendor/splash/tasking-bundle/src
Where to look first, in this order:
src/DependencyInjection/Configuration.php — this is the single most valuable file. It enumerates every config key the bundle accepts. There is likely no README covering them.src/DependencyInjection/*Extension.php — shows which services get registered, which are conditional on config, and which parameters are set.src/Resources/config/services.yaml (or .xml) — the actual service IDs and their tags. Tags are the extension points.src/Command/ — any *Command classes reveal the intended CLI entry points, and --help on them is your de facto manual.src/Entity/ or src/Model/ — the task/job data model.composer.json inside the vendor dir — the hard constraints on PHP and Symfony versions. Check these against your app before you write a line of integration code.First use case. The realistic one is: enqueue a unit of work from a controller or message handler, then have a worker process it out-of-band. Get the smallest possible task running end-to-end — one task class, one dispatch, one worker invocation via the console — before touching config. If you can't get that loop closed in an hour, stop and evaluate alternatives (Symfony Messenger with messenger:consume plus scheduler covers most of the same ground and is first-party).
Sanity gate. Before committing, confirm the bundle installs cleanly on your Symfony version. A 2020-era bundle will not have been tested against Symfony 6.x/7.x and may fail at container compile time rather than at runtime — which is at least a fast failure.
Wrap it, don't sprinkle it. The highest-leverage pattern with an unmaintained dependency is a thin application-owned seam:
interface TaskDispatcherInterface
{
public function dispatch(TaskInterface $task): void;
}
final class SplashTaskDispatcher implements TaskDispatcherInterface
{
public function __construct(private TaskManagerInterface $manager) {}
public function dispatch(TaskInterface $task): void
{
$this->manager->add($task);
}
}
Consumers depend on your interface, not on Splash\TaskingBundle\*. When the bundle dies — and statistically it will — you swap one class instead of grepping the codebase.
Define tasks as services, not as new-ed objects. If the bundle resolves task handlers from the container (most Symfony task bundles do), your task classes need to be autowired services so they can receive repositories, HTTP clients, and loggers. Register them explicitly if autoconfiguration doesn't pick up the bundle's tag:
services:
App\Task\SyncOrdersTask:
tags: ['splash.tasking.task'] # verify the exact tag in services.yaml
Delegate the trigger to cron, not to the bundle. A 2020 bundle almost certainly does not ship a long-running daemon supervisor. Run its worker command on a schedule:
* * * * * cd /var/www/app && php bin/console splash:tasking:run --env=prod --no-interaction >> /var/log/tasking.log 2>&1
Keep the command name honest by checking bin/console list splash after install.
Keep tasks idempotent. Any task queue that survives a restart, a timeout, or a mid-flight deploy will redeliver. Design every task so running it twice is harmless — upsert instead of insert, check-then-act with a lock, or carry a dedupe key. This is the pattern that matters most day-to-day and it's independent of whatever this bundle does internally.
Integrate with your observability. Whatever the bundle logs, add your own structured log line at task start and finish with the task ID. Without it, debugging a failed background job in a package nobody else uses is guesswork.
Feature-flag the subsystem. Because the dependency risk is real, put the whole tasking path behind a flag or a separate deploy target. If you need to rip it out under pressure, you want one boolean between you and a production incident.
Abandonment is the headline. Last release September 2020. That predates Symfony 6, PHP 8.1, and every security advisory since. There is no upgrade path and no maintainer to ask. Budget for the possibility that you fork it. The MIT license at least makes that legal and uncomplicated.
Zero dependents cuts both ways. No one has hit the edge cases before you. Expect to be the first person to encounter basic bugs. On the upside, vendor/splash/tasking-bundle is small and entirely readable — you can debug to the bottom of the stack without hitting a compiled binary or a closed-source layer.
Version constraints bite at compile time. If composer require resolves, you're probably fine; if it fights you, do not use --ignore-platform-reqs to force it. A bundle compiled against a different DI container API will throw confusing ServiceNotFoundException or InvalidArgumentException errors at cache:clear, and those errors will point at generated files rather than the real cause.
Config quirks live in Configuration.php. Undocumented options are the norm here. Read the tree builder and note which nodes have defaults vs. which are isRequired(). Missing required nodes fail at container compile with a message naming the node — useful, but only if you know where to look.
Debugging checklist when a task silently doesn't run:
bin/console debug:container --tag=<the-bundle-tag> — is your task even registered?bin/console debug:event-dispatcher — if the bundle hooks kernel events, see whether the listener is attached.Extension points are tags and compiler passes. With no docs, tags are your API. Grep the services.yaml inside the bundle for tags: — every tag name there is a supported extension point, and the compiler pass consuming it defines the contract. Anything not tagged is effectively private.
Testing. Don't try to integration-test against the bundle's real queue. Test your task classes as plain services (they're just callables or invokable objects), and assert on a fake TaskDispatcherInterface. That keeps your test suite independent of whether the bundle works at all.
The honest recommendation. For a greenfield Symfony app in 2024+, use Symfony Messenger plus the Scheduler component instead. You get a maintained first-party solution with the same mental model. Reach for splash/tasking-bundle only if you're maintaining an existing app already coupled to it, or if you've read the source and it does one specific thing you can't replicate cheaply. Given 1 star and 0 dependents, the burden of proof is on the bundle, not on the alternatives.
How can I help you explore Laravel packages today?