Introduction
Shopware 6.7 introduces significant enhancements to its scheduled task system, providing developers with more robust and flexible options for executing background jobs. Scheduled tasks are essential components for automating routine operations such as data cleanup, report generation, inventory synchronization, and various maintenance activities. This technical guide will walk you through the complete process of creating and registering custom scheduled tasks in Shopware 6.7.
Understanding Scheduled Tasks in Shopware 6.7
Scheduled tasks in Shopware 6.7 operate on a new architecture that improves performance and reliability compared to previous versions. The system now leverages Symfony's Messenger component more effectively, providing better queue management and task execution monitoring. Each scheduled task is registered as a service and can be configured with specific intervals, execution conditions, and priority levels.
The core components of a scheduled task include:
- Task definition and registration
- Execution logic implementation
- Configuration through YAML files
- Database integration for task tracking
- Event handling and logging
Prerequisites and Setup
Before implementing custom scheduled tasks, ensure you have:
- Shopware 6.7+ installed
- Basic understanding of Symfony services and dependency injection
- Familiarity with Shopware's service container and plugin architecture
- Access to the command line for cache clearing operations
Creating a Custom Scheduled Task Service
The first step in creating a custom scheduled task is implementing the task logic itself. Here's how to create a basic scheduled task service:
<?php declare(strict_types=1);
namespace MyPlugin\ScheduledTask;
use Shopware\Core\Framework\MessageQueue\ScheduledTask\ScheduledTask;
use Symfony\Component\Messenger\Attribute\AsMessageHandler;
class MyCustomScheduledTask extends ScheduledTask
{
public static function getHandledMessages(): iterable
{
return [self::class];
}
public static function getTaskName(): string
{
return 'my_plugin.custom_task';
}
public static function getDefaultInterval(): int
{
return 3600; // 1 hour in seconds
}
}
Implementing the Task Handler
Next, you need to create a message handler that will execute your task logic:
<?php declare(strict_types=1);
namespace MyPlugin\MessageHandler;
use Psr\Log\LoggerInterface;
use Shopware\Core\Framework\MessageQueue\ScheduledTask\ScheduledTaskHandler;
use Symfony\Component\Messenger\Attribute\AsMessageHandler;
use MyPlugin\ScheduledTask\MyCustomScheduledTask;
#[AsMessageHandler(handles: MyCustomScheduledTask::class)]
class MyCustomScheduledTaskHandler extends ScheduledTaskHandler
{
private LoggerInterface $logger;
public function __construct(
LoggerInterface $logger
) {
$this->logger = $logger;
}
public function handle(ScheduledTask $task): void
{
try {
$this->logger->info('Starting MyCustomScheduledTask execution');
// Your custom task logic goes here
$this->performDatabaseCleanup();
$this->sendNotificationEmails();
$this->logger->info('MyCustomScheduledTask completed successfully');
} catch (\Exception $e) {
$this->logger->error('Error in MyCustomScheduledTask: ' . $e->getMessage());
throw $e;
}
}
private function performDatabaseCleanup(): void
{
// Implementation for database cleanup operations
}
private function sendNotificationEmails(): void
{
// Implementation for email notifications
}
}
Registering the Scheduled Task
The registration process involves several steps to ensure proper integration with Shopware's system. Here's the complete registration approach:
Service Configuration in services.xml
<?xml version="1.0" encoding="UTF-8"?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services
http://symfony.com/schema/dic/services/services-1.0.xsd">
<services>
<!-- Scheduled Task Service -->
<service id="MyPlugin\ScheduledTask\MyCustomScheduledTask">
<tag name="shopware.scheduled.task"/>
</service>
<!-- Message Handler -->
<service id="MyPlugin\MessageHandler\MyCustomScheduledTaskHandler">
<argument type="service" id="logger"/>
<tag name="messenger.message_handler"/>
</service>
</services>
</container>
Plugin Configuration
In your plugin's src/MyPlugin.php file, ensure proper service registration:
<?php declare(strict_types=1);
namespace MyPlugin;
use Shopware\Core\Framework\Plugin;
use Symfony\Component\DependencyInjection\ContainerBuilder;
class MyPlugin extends Plugin
{
public function build(ContainerBuilder $container): void
{
parent::build($container);
// Additional container configuration if needed
}
}
Advanced Configuration Options
Shopware 6.7 allows for extensive customization of scheduled tasks through various configuration options:
Custom Interval and Execution Settings
<?php declare(strict_types=1);
namespace MyPlugin\ScheduledTask;
use Shopware\Core\Framework\MessageQueue\ScheduledTask\ScheduledTask;
use Symfony\Component\Messenger\Attribute\AsMessageHandler;
class AdvancedScheduledTask extends ScheduledTask
{
public static function getHandledMessages(): iterable
{
return [self::class];
}
public static function getTaskName(): string
{
return 'my_plugin.advanced_task';
}
public static function getDefaultInterval(): int
{
// Custom interval in seconds (e.g., 15 minutes)
return 900;
}
public static function getInterval(): array
{
// Define multiple interval options
return [
'minute' => 60,
'hour' => 3600,
'day' => 86400,
];
}
public static function isRunOnce(): bool
{
// Return true if task should run only once
return false;
}
}
Conditional Execution Logic
<?php declare(strict_types=1);
namespace MyPlugin\MessageHandler;
use Shopware\Core\Framework\MessageQueue\ScheduledTask\ScheduledTaskHandler;
use Symfony\Component\Messenger\Attribute\AsMessageHandler;
use MyPlugin\ScheduledTask\ConditionalScheduledTask;
#[AsMessageHandler(handles: ConditionalScheduledTask::class)]
class ConditionalScheduledTaskHandler extends ScheduledTaskHandler
{
public function handle(ScheduledTask $task): void
{
// Check execution conditions before proceeding
if (!$this->shouldExecute()) {
return;
}
// Execute task logic
$this->executeTask();
}
private function shouldExecute(): bool
{
// Implement your condition checking logic
// For example, check system load, specific environment, etc.
return true;
}
private function executeTask(): void
{
// Main execution logic
}
}
Database Integration and Task Tracking
Proper database integration is crucial for monitoring task execution and maintaining system integrity:
<?php declare(strict_types=1);
namespace MyPlugin\ScheduledTask;
use Doctrine\DBAL\Connection;
use Shopware\Core\Framework\MessageQueue\ScheduledTask\ScheduledTask;
class DatabaseAwareScheduledTask extends ScheduledTask
{
private Connection $connection;
public function __construct(Connection $connection)
{
$this->connection = $connection;
}
public static function getTaskName(): string
{
return 'my_plugin.database_task';
}
public static function getDefaultInterval(): int
{
return 1800; // 30 minutes
}
private function logTaskExecution(string $status): void
{
$this->connection->insert('scheduled_task_log', [
'task_name' => self::getTaskName(),
'executed_at' => new \DateTime(),
'status' => $status,
'details' => json_encode(['message' => 'Task executed successfully'])
]);
}
}
Performance Optimization Considerations
When implementing scheduled tasks, consider these optimization strategies:
Batch Processing
public function handle(ScheduledTask $task): void
{
$batchSize = 100;
$offset = 0;
do {
$records = $this->fetchRecords($offset, $batchSize);
if (empty($records)) {
break;
}
$this->processBatch($records);
$offset += $batchSize;
// Prevent memory exhaustion
gc_collect_cycles();
} while (count($records) === $batchSize);
}
Resource Management
public function handle(ScheduledTask $task): void
{
$memoryLimit = ini_get('memory_limit');
$startTime = microtime(true);
try {
// Task execution logic
$executionTime = microtime(true) - $startTime;
$this->logExecutionMetrics($executionTime, $memoryLimit);
} catch (\Exception $e) {
$this->logger->error('Task execution failed: ' . $e->getMessage());
throw $e;
}
}
Monitoring and Debugging
Effective monitoring is essential for maintaining scheduled tasks. Shopware 6.7 provides built-in logging capabilities:
public function handle(ScheduledTask $task): void
{
$this->logger->info('Scheduled task started', [
'task_name' => self::getTaskName(),
'execution_time' => date('Y-m-d H:i:s')
]);
try {
// Task logic
$this->logger->info('Scheduled task completed successfully', [
'task_name' => self::getTaskName()
]);
} catch (\Exception $e) {
$this->logger->error('Scheduled task failed', [
'task_name' => self::getTaskName(),
'error' => $e->getMessage(),
'trace' => $e->getTraceAsString()
]);
throw $e;
}
}
Testing Your Scheduled Task
Comprehensive testing ensures your scheduled tasks function correctly:
<?php declare(strict_types=1);
namespace MyPlugin\Test;
use PHPUnit\Framework\TestCase;
use MyPlugin\MessageHandler\MyCustomScheduledTaskHandler;
use MyPlugin\ScheduledTask\MyCustomScheduledTask;
class ScheduledTaskTest extends TestCase
{
public function testTaskHandlerExecution(): void
{
$handler = new MyCustomScheduledTaskHandler($this->createMock(LoggerInterface::class));
$task = new MyCustomScheduledTask();
$handler->handle($task);
// Assert expected behavior
$this->assertTrue(true, 'Task executed without errors');
}
}
Deployment and Maintenance
When deploying custom scheduled tasks:
- Clear all caches after implementation
- Verify task registration in the database
- Monitor execution logs for errors
- Set appropriate intervals based on system requirements
- Implement proper error handling and notification systems
Conclusion
Shopware 6.7's enhanced scheduled task system provides developers with powerful tools for automating background operations. By following this comprehensive guide, you can create robust, efficient, and maintainable custom scheduled tasks that integrate seamlessly with Shopware's architecture.
The key to successful implementation lies in understanding the underlying architecture, implementing proper error handling, optimizing performance, and maintaining clear monitoring capabilities. With these principles in mind, your custom scheduled tasks will contribute to a more efficient and reliable e-commerce platform.
Remember to test thoroughly in staging environments before deploying to production, and always consider the impact of task execution on system resources and user experience.