abc/job-server-bundle
Symfony bundle for asynchronous distributed job processing via php-enqueue. Supports jobs, batches, sequences, free composition, status tracking, cancellation/restart, cron jobs (with AbcSchedulerBundle), plus a JSON REST API, PHP client, and OpenAPI docs.
Install the Bundle
composer require abc/job-server-bundle
Ensure EnqueueBundle is installed and configured with a transport (e.g., Redis, RabbitMQ, or Doctrine).
Configure the Bundle
Update config/packages/abc_job_server.yaml:
abc_job_server:
transport: default # or your custom transport name
api:
enabled: true # Enable REST API if needed
Set Up Database Run migrations to create job-related tables:
bin/console doctrine:migrations:diff
bin/console doctrine:migrations:migrate
First Job Dispatch
Define a job class (e.g., src/Job/MyJob.php):
namespace App\Job;
use Abc\JobServerBundle\Job\JobInterface;
class MyJob implements JobInterface {
public function run(): void {
// Your job logic here
}
}
Dispatch it via CLI or controller:
bin/console abc:job:dispatch App\Job\MyJob
Verify Job Status
Check job status via API (/api/jobs/{id}) or CLI:
bin/console abc:job:status <job-id>
bin/console abc:job:dispatch App\Job\MyJob --param=value
use Abc\JobServerBundle\Job\JobDispatcher;
$dispatcher = $container->get(JobDispatcher::class);
$dispatcher->dispatch(new MyJob($param));
use Abc\JobServerBundle\Job\Sequence;
$sequence = new Sequence();
$sequence->addJob(new JobA());
$sequence->addJob(new JobB());
$dispatcher->dispatch($sequence);
use Abc\JobServerBundle\Job\Batch;
$batch = new Batch();
$batch->addJob(new JobX());
$batch->addJob(new JobY());
$dispatcher->dispatch($batch);
GET /api/jobs → List jobs.GET /api/jobs/{id} → Job details.POST /api/jobs/{id}/cancel → Cancel a job.bin/console abc:job:list # List all jobs
bin/console abc:job:status <id> # Check job status
bin/console abc:job:cancel <id> # Cancel a job
AbcSchedulerBundle)config/packages/abc_scheduler.yaml:
abc_scheduler:
jobs:
my_cron_job:
class: App\Job\MyCronJob
schedule: "0 0 * * *" # Run daily at midnight
JobDispatcher or JobRepository into services for seamless job handling.JobStartedEvent, JobFailedEvent):
use Abc\JobServerBundle\Event\JobEvent;
$eventDispatcher->addListener(JobEvent::JOB_STARTED, function (JobEvent $event) {
// Log or notify when a job starts
});
JobState enum or create custom states by implementing JobInterface.Transport Configuration Mismatch
abc_job_server.transport setting matches your enqueue transport configuration.bin/console debug:container abc_job_server.transport to verify the active transport.Database Schema Updates
bin/console doctrine:migrations:diff
bin/console doctrine:migrations:migrate
Job Serialization Issues
__serialize() and __unserialize() in custom jobs or use #[AsArray] for DTOs.API Authentication
# config/packages/security.yaml
firewalls:
api:
pattern: ^/api/jobs
stateless: true
json_login:
check_path: /api/login
Worker Management
bin/console enqueue:consume --transport=default
Job Stuck in Queue?
bin/console abc:job:retry <job-id>
Job Fails Silently?
config/packages/monolog.yaml:
handlers:
job_server:
type: stream
path: "%kernel.logs_dir%/%kernel.environment%.job-server.log"
level: debug
channels: ["abc_job_server"]
API Returns 500 Errors?
/api/doc) and check for missing dependencies (e.g., AbcSchedulerBundle for cron jobs).Custom Job States
Extend the JobState enum or create a custom state machine by implementing JobStateProviderInterface.
Transport-Specific Logic
Override the JobTransport service to customize message handling (e.g., for SNS/SQS).
Job Metadata
Add custom metadata to jobs via the setMetadata() method:
$job = new MyJob();
$job->setMetadata(['priority' => 'high']);
Event-Driven Extensions
Listen to events like JobFailedEvent to trigger alerts or retries:
$eventDispatcher->addListener(JobEvent::JOB_FAILED, function (JobFailedEvent $event) {
// Send Slack notification or log to Sentry
});
Testing Jobs
Use the JobTestCase base class or mock the JobDispatcher in PHPUnit:
$dispatcher = $this->createMock(JobDispatcher::class);
$dispatcher->expects($this->once())->method('dispatch');
How can I help you explore Laravel packages today?