21torr/task-manager
Small wrapper around symfony/messenger that simplifies task management in PHP/Symfony apps. Helps you define, dispatch, and handle tasks with a cleaner API while keeping Messenger under the hood. Includes documentation for quick setup and usage.
composer require 21torr/task-manager
config/bundles.php:
return [
// ...
TaskManagerBundle::class => ['all' => true],
];
config/packages/messenger.yaml:
framework:
messenger:
transports:
async: '%env(MESSENGER_TRANSPORT_DSN)%'
task_manager_internals: 'doctrine://default?queue_name=task_manager_internals'
php bin/console doctrine:migrations:diff
php bin/console doctrine:migrations:migrate
Create a task class extending Task:
use TaskManagerBundle\Task\Task;
class SendEmailTask extends Task
{
public function __construct(
private string $email,
private string $message
) {}
public function run(): void
{
// Task logic here
mail($this->email, 'Subject', $this->message);
}
}
Dispatch the task via the TaskManager:
use TaskManagerBundle\TaskManager\TaskManager;
class SomeService
{
public function __construct(private TaskManager $taskManager) {}
public function sendEmail(): void
{
$task = new SendEmailTask('user@example.com', 'Hello!');
$this->taskManager->enqueue($task);
}
}
Start the worker process:
php bin/console task-manager:run-worker async --limit=10
Automatic Registration:
The bundle automatically discovers tasks via the RegisterTasksEvent. No manual registration is required for basic usage.
Custom Task Metadata:
Extend task metadata by implementing TaskMetadataInterface:
use TaskManagerBundle\Task\TaskMetadataInterface;
class SendEmailTask extends Task implements TaskMetadataInterface
{
public function getKey(): string
{
return 'send_email';
}
public function getDescription(): string
{
return 'Sends an email to the specified address';
}
}
Use the TaskScheduler for delayed or recurring tasks:
use TaskManagerBundle\TaskManager\TaskScheduler;
class SomeService
{
public function __construct(
private TaskScheduler $scheduler,
private TaskManager $taskManager
) {}
public function scheduleEmail(): void
{
$task = new SendEmailTask('user@example.com', 'Hello!');
$this->scheduler->schedule($task, new \DateTimeImmutable('+1 hour'));
}
}
Post-Run Tasks:
Use DispatchAfterRunTask to chain tasks:
use TaskManagerBundle\Task\DispatchAfterRunTask;
class SendEmailTask extends Task
{
public function run(): void
{
// Task logic
$this->taskManager->enqueue(
new DispatchAfterRunTask(
new LogEmailSentTask($this->email)
)
);
}
}
Logging Failures:
The bundle automatically logs task failures in the TaskLog table. Access logs via:
php bin/console task-manager:log
Queue Inspection:
php bin/console task-manager:queue async
Task Debugging:
php bin/console task-manager:debug
Log Cleanup:
php bin/console task-manager:clean-log --days=30
Task Class Requirement:
All tasks must extend TaskManagerBundle\Task\Task. Forgetting this will cause runtime errors.
ULID Format:
Ensure task IDs follow the ULID format (e.g., 01H5Z2X3Y4...). The bundle validates this during enqueueing.
Internal Tasks:
Avoid manually dispatching tasks marked as TaskManagerInternalTask. These are reserved for bundle internals.
Deprecated Methods:
TaskLog::getTaskObject() is deprecated. Use TaskDetailsNormalizer::deserializeTask() instead.getId()) are deprecated in favor of direct property access.Requeueing Tasks in Development:
Use the task-manager:requeue command to reprocess failed tasks:
php bin/console task-manager:requeue <task-id>
Worker Memory Issues:
The run-worker command defaults to handling 5 messages at a time. Increase the limit for batch processing:
php bin/console task-manager:run-worker async --limit=50
Log Retention:
The LogCleaner runs automatically but can be triggered manually:
php bin/console task-manager:clean-log --days=7
Custom Task Handlers:
Extend TaskHandlerInterface to add pre/post-processing logic:
use TaskManagerBundle\Task\TaskHandlerInterface;
class CustomTaskHandler implements TaskHandlerInterface
{
public function handle(Task $task, TaskRun $run): void
{
// Custom logic before/after task execution
}
}
Register the handler in config/packages/task_manager.yaml:
task_manager:
handlers:
- App\CustomTaskHandler
Custom Transports:
Add new transports in messenger.yaml and configure the bundle to use them:
framework:
messenger:
transports:
custom_transport: 'doctrine://default?queue_name=custom_queue'
Event Listeners:
Listen to task events (e.g., TaskEvent):
use TaskManagerBundle\Event\TaskEvent;
class TaskListener
{
public function onTaskRun(TaskEvent $event): void
{
// Handle task run events
}
}
Register the listener in services.yaml:
services:
App\TaskListener:
tags:
- { name: 'kernel.event_listener', event: 'task.run', method: 'onTaskRun' }
Log Cleanup:
The LogCleaner runs asynchronously. For large log tables, manually trigger cleanup with a higher limit:
php bin/console task-manager:clean-log --limit=10000
Worker Concurrency:
Adjust the MESSENGER_CONCURRENCY environment variable to control parallel task execution:
php bin/console task-manager:run-worker async --limit=10 -e MESSENGER_CONCURRENCY=5
Task Serialization: Complex task objects may cause serialization issues. Ensure all dependencies are serializable or use DTOs.
Hidden Internal Tasks:
To exclude internal tasks from logs, configure in task_manager.yaml:
task_manager:
log:
hide_internal_tasks: true
Transport Priorities:
The bundle uses task_manager_internals for internal messages. Ensure this transport is configured separately to avoid mixing with user tasks.
PHP Version: The bundle requires PHP 8.5+. Downgrading may break functionality (e.g., ULID handling in v3.2.0+).
How can I help you explore Laravel packages today?