From 1b03512d371b4fec1360aec19aa7f4654a589c37 Mon Sep 17 00:00:00 2001 From: Steven Ngesera Date: Sat, 9 Nov 2024 00:41:14 +0300 Subject: [PATCH] Scheduling Comlete, next step Notification with channels: telegram,slack,twilio,nexmo,broadcast --- .env.example | 1 + lib/cache.php | 1 - .../Core/Commands/Hm_QueueWorkCommand.php | 14 + .../Core/Commands/Hm_ScheduleRunCommand.php | 22 +- .../Core/Commands/Hm_SchedulerWorkCommand.php | 100 +++++++ services/Core/Hm_Container.php | 22 +- services/Core/Jobs/Hm_BaseJob.php | 33 ++- services/Core/Queue/Hm_JobDispatcher.php | 1 + services/Core/Queue/Hm_QueueManager.php | 1 + services/Core/Queue/Hm_QueueWorker.php | 1 - services/Core/Scheduling/Hm_CacheMutex.php | 4 +- services/Core/Scheduling/Hm_ScheduledTask.php | 245 +++++++++++++----- services/Core/Scheduling/Hm_Scheduler.php | 24 +- services/Events/Hm_NewEmailProcessedEvent.php | 2 +- services/Hm_ConsoleKernal.php | 29 --- services/Hm_ConsoleKernel.php | 12 +- services/Hm_bootstrap.php | 2 +- services/Jobs/Hm_ProcessNewEmail.php | 4 + .../Providers/Hm_EventServiceProvider.php | 10 + .../Providers/Hm_QueueServiceProvider.php | 15 +- .../Providers/Hm_SchedulerServiceProvider.php | 6 +- services/readme.rd | 25 +- 22 files changed, 441 insertions(+), 133 deletions(-) create mode 100644 services/Core/Commands/Hm_SchedulerWorkCommand.php delete mode 100644 services/Hm_ConsoleKernal.php diff --git a/.env.example b/.env.example index 214b41e50..b39df9224 100644 --- a/.env.example +++ b/.env.example @@ -212,6 +212,7 @@ WIN_CACERT_DIR= JS_EXCLUDE_DEPS= +QUEUE_ENABLED=false QUEUE_DRIVER=database AWS_ACCESS_KEY_ID='your-aws-access-key' diff --git a/lib/cache.php b/lib/cache.php index 336ef8f78..1f54e0716 100644 --- a/lib/cache.php +++ b/lib/cache.php @@ -603,7 +603,6 @@ protected function noop_get($key, $default) { * @return string */ protected function key_hash($key) { - dd($this->session->get('fingerprint')); return sprintf('hm_cache_%s', hash('sha256', (sprintf('%s%s%s%s', $key, SITE_ID, $this->session->get('fingerprint'), $this->session->get('username'))))); } diff --git a/services/Core/Commands/Hm_QueueWorkCommand.php b/services/Core/Commands/Hm_QueueWorkCommand.php index c5ea0d875..e6fce0d1f 100644 --- a/services/Core/Commands/Hm_QueueWorkCommand.php +++ b/services/Core/Commands/Hm_QueueWorkCommand.php @@ -11,10 +11,17 @@ use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\DependencyInjection\ContainerInterface; +/** + * Class Hm_QueueWorkCommand + * @package Services\Core\Commands + */ class Hm_QueueWorkCommand extends Hm_BaseCommand { protected static $defaultName = 'queue:work'; + /** + * Configure the command. + */ protected function configure() { $this @@ -27,6 +34,13 @@ protected function configure() ->addOption('tries', null, InputOption::VALUE_OPTIONAL, 'Number of times to attempt a job before logging it failed', 1); } + /** + * Execute the console command. + * + * @param InputInterface $input + * @param OutputInterface $output + * @return int Command exit code. + */ protected function execute(InputInterface $input, OutputInterface $output): int { $connection = $input->getArgument('connection') ?: env('QUEUE_DRIVER', 'database'); diff --git a/services/Core/Commands/Hm_ScheduleRunCommand.php b/services/Core/Commands/Hm_ScheduleRunCommand.php index 1cdf3b20c..3152c8a16 100644 --- a/services/Core/Commands/Hm_ScheduleRunCommand.php +++ b/services/Core/Commands/Hm_ScheduleRunCommand.php @@ -8,11 +8,22 @@ use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; +/** + * Class Hm_ScheduleRunCommand + * @package Services\Core\Commands + */ class Hm_ScheduleRunCommand extends Hm_BaseCommand { - // Default name for the command + /** + * The name of the command. + * + * @var string + */ protected static $defaultName = 'schedule:run'; + /** + * Configure the command. + */ protected function configure() { $this @@ -21,11 +32,16 @@ protected function configure() ; } + /** + * Execute the console command. + * + * @param InputInterface $input + * @param OutputInterface $output + * @return int Command exit code. + */ protected function execute(InputInterface $input, OutputInterface $output): int { - // Get the scheduler instance from the container $scheduler = Hm_Container::getContainer()->get('scheduler'); - // Run the tasks that are due $scheduler->run(); $output->writeln("All due scheduled tasks have been executed."); diff --git a/services/Core/Commands/Hm_SchedulerWorkCommand.php b/services/Core/Commands/Hm_SchedulerWorkCommand.php new file mode 100644 index 000000000..52a4ec3a2 --- /dev/null +++ b/services/Core/Commands/Hm_SchedulerWorkCommand.php @@ -0,0 +1,100 @@ +setDescription('Continuously run the scheduler to execute due tasks') + ->setHelp('This command runs the scheduler in a loop to continuously check and execute scheduled tasks.'); + } + + /** + * Execute the console command. + * + * @param InputInterface $input + * @param OutputInterface $output + * @return int Command exit code. + */ + protected function execute(InputInterface $input, OutputInterface $output): int + { + $scheduler = Hm_Container::getContainer()->get('scheduler'); + $output->writeln("Scheduler started. Press Ctrl+C to stop."); + + if (function_exists('pcntl_signal')) { + pcntl_signal(SIGINT, function () { + $this->shouldStop = true; + }); + } + + while (!$this->shouldStop) { + foreach ($scheduler->getTasks() as $task) { + $taskId = spl_object_hash($task); + $currentTime = new \DateTime('now', new \DateTimeZone($task->getTimezone())); + + $lastRunTime = isset($this->lastRunTimes[$taskId]) ? $this->lastRunTimes[$taskId] : $currentTime; + + $this->lastRunTimes[$taskId] = $currentTime; + + if ($task->isDue() && $currentTime > $lastRunTime) { + $output->writeln("Running task: {$task->getName()} at " . $currentTime->format('Y-m-d H:i:s')); + $task->run(); + $output->writeln("Task: {$task->getName()} added to queue"); + } + } + + // Wait one minute before the next loop iteration + sleep(60); + + // Dispatch any pending signals + if (function_exists('pcntl_signal_dispatch')) { + pcntl_signal_dispatch(); + } + } + + $output->writeln("Scheduler stopped gracefully."); + + return Command::SUCCESS; + } + + /** + * Stops the scheduler loop gracefully. + */ + public function stop() + { + $this->shouldStop = true; + } +} diff --git a/services/Core/Hm_Container.php b/services/Core/Hm_Container.php index b50ef16f3..3805f348b 100644 --- a/services/Core/Hm_Container.php +++ b/services/Core/Hm_Container.php @@ -8,6 +8,10 @@ use Symfony\Component\DependencyInjection\ContainerBuilder; use Services\Providers\{Hm_CommandServiceProvider, Hm_EventServiceProvider, Hm_SchedulerServiceProvider, Hm_QueueServiceProvider}; +/** + * Class Hm_Container + * @package Services\Core + */ class Hm_Container { private static $container = null; @@ -16,6 +20,12 @@ class Hm_Container private function __construct() {} private function __clone() {} + /** + * Set the container + * + * @param ContainerBuilder $containerBuilder + * @return ContainerBuilder + */ public static function setContainer(ContainerBuilder $containerBuilder): ContainerBuilder { if (self::$container === null) { @@ -25,12 +35,17 @@ public static function setContainer(ContainerBuilder $containerBuilder): Contain return self::$container; } + /** + * Bind the container + * + * @return ContainerBuilder + */ public static function bind(): ContainerBuilder { $config = self::$container->get('config'); if ($config->get('queue_enabled')) { - + if ($config->get('queue_driver') === 'database') { // Register Hm_DB self::$container->set('db.connection', Hm_DB::connect(self::$container->get('config'))); @@ -67,6 +82,11 @@ public static function bind(): ContainerBuilder return self::$container; } + /** + * Get the container + * + * @return ContainerBuilder + */ public static function getContainer(): ContainerBuilder { return self::$container; diff --git a/services/Core/Jobs/Hm_BaseJob.php b/services/Core/Jobs/Hm_BaseJob.php index 9cd7a88e4..6e1073754 100644 --- a/services/Core/Jobs/Hm_BaseJob.php +++ b/services/Core/Jobs/Hm_BaseJob.php @@ -6,7 +6,7 @@ abstract class Hm_BaseJob implements Hm_Job { - public string $driver = 'database'; + public string $driver = ''; public int $tries = 3; protected int $attempts = 0; @@ -14,26 +14,53 @@ public function __construct(protected array $data = []) { $this->data = $data; } + /** + * Execute the job. + * + * @return void + */ public function handle(): void {} + /** + * Handle a job failure. + * + * @return void + */ public function failed(): void {} + /** + * Get the driver name for the job. + * + * @return int + */ public function getDriver(): string { return $this->driver; } + /** + * Get the number of times the job has been attempted. + * + * @return int + */ public function getAttempts(): int { return $this->attempts; } - // Method to increment the attempt count + /** + * Method to increment the attempt count + * + */ public function incrementAttempts(): void { $this->attempts++; } - // Check if the job has exceeded the max attempts + /** + * Determine if the job has exceeded the maximum number of attempts. + * + * @return bool + */ public function hasExceededMaxAttempts(): bool { return $this->attempts >= $this->tries; diff --git a/services/Core/Queue/Hm_JobDispatcher.php b/services/Core/Queue/Hm_JobDispatcher.php index 64084269b..30d929c14 100644 --- a/services/Core/Queue/Hm_JobDispatcher.php +++ b/services/Core/Queue/Hm_JobDispatcher.php @@ -23,6 +23,7 @@ class Hm_JobDispatcher static public function dispatch(Hm_BaseJob $job): void { if (is_subclass_of($job, Hm_ShouldQueue::class)) { $driver = $job->driver; + dd($driver); $queueDriver = Hm_Container::getContainer()->get('queue.manager')->getDriver($driver); if ($queueDriver) { $queueDriver->push($job); diff --git a/services/Core/Queue/Hm_QueueManager.php b/services/Core/Queue/Hm_QueueManager.php index 6afb42692..9027f798f 100644 --- a/services/Core/Queue/Hm_QueueManager.php +++ b/services/Core/Queue/Hm_QueueManager.php @@ -23,6 +23,7 @@ public function addDriver(string $name, Hm_ShouldQueue $driver): void public function getDriver(string $name): Hm_ShouldQueue { + dump("Getting driver $name"); return $this->drivers[$name]; } } diff --git a/services/Core/Queue/Hm_QueueWorker.php b/services/Core/Queue/Hm_QueueWorker.php index 011c4ba5c..e70cd0181 100644 --- a/services/Core/Queue/Hm_QueueWorker.php +++ b/services/Core/Queue/Hm_QueueWorker.php @@ -30,7 +30,6 @@ public function work(): void { while ($job = $this->queue->pop()) { try { - // dd($job); $this->queue->process($job); } catch (\Exception $e) { // $job->failed(); diff --git a/services/Core/Scheduling/Hm_CacheMutex.php b/services/Core/Scheduling/Hm_CacheMutex.php index 8e3cca327..cb5b1ad77 100644 --- a/services/Core/Scheduling/Hm_CacheMutex.php +++ b/services/Core/Scheduling/Hm_CacheMutex.php @@ -67,8 +67,8 @@ public function release($task) */ private function getMutexKey($task) { - return 'mutex_' . hash('sha256', get_class($task) . $task->name . json_encode($task->command)); - // return 'mutex_' . hash('sha256', $task->name); + // return 'mutex_' . hash('sha256', get_class($task) . $task->name . json_encode($task->command)); + return 'mutex_' . hash('sha256', $task->name); } /** diff --git a/services/Core/Scheduling/Hm_ScheduledTask.php b/services/Core/Scheduling/Hm_ScheduledTask.php index 81dc0f990..de8258e54 100644 --- a/services/Core/Scheduling/Hm_ScheduledTask.php +++ b/services/Core/Scheduling/Hm_ScheduledTask.php @@ -8,18 +8,76 @@ class Hm_ScheduledTask { use Hm_ScheduleFrequencyManager; + /** + * The caallback to run + * + */ private $callback; + /** + * The next run time + * + * @var string + */ private $nextRunTime; + /** + * check if the task is enabled + * + * @var boolean + */ private $isEnabled = true; + /** + * The task name + * + * @var string + */ private $name; + /** + * The task name + * + * @var string + */ private $description; + /** + * The task name + * + * @var array + */ private $tags = []; + /** + * The last run time + * + */ private $lastRunTime; - - private $maxRetries = 3; - private $retryInterval = 60; // Interval in seconds between retries - private $retryCount = 0; // Track the number of retries attempted - + /** + * The maximum number of retries + * + * @var int + */ + private int $maxRetries = 3; + + /** + * Interval in seconds between retries + * + * @var int + */ + private int $retryInterval = 60; + /** + * Track the number of retries attempted + * + * @var int + */ + private int $retryCount = 0; + + /** + * Create a new scheduled task + * + * @param callable $callback + * @param string $name + * @param string $description + * @param array $tags + * @param string $timezone + * @param string $expression + */ public function __construct(callable $callback, $name = '', $description = '', $tags = [], $timezone = 'UTC', $expression = '* * * * *') { $this->callback = $callback; @@ -30,11 +88,21 @@ public function __construct(callable $callback, $name = '', $description = '', $ $this->expression = $expression; } + /** + * Get the task name + * + * @return string + */ public function getName() { return $this->name; } + /** + * Check if the task is due to run + * + * @return bool + */ public function isDue() { if ($this->isEnabled) { @@ -44,6 +112,19 @@ public function isDue() return false; } + /** + * Get the next run time + * + * @return \DateTime + */ + public function getTimezone() + { + return $this->timezone; + } + + /** + * Run the scheduled task + */ public function run() { if (!$this->isDue()) { @@ -72,101 +153,121 @@ public function run() $this->scheduleNextRun(); } - private function handleRetry(\Exception $e) - { - if ($this->retryCount < $this->maxRetries) { - $this->retryCount++; - $retryTime = $this->retryInterval * $this->retryCount; - - // Log the retry attempt - error_log("Retry attempt {$this->retryCount} for task {$this->name}, will retry in {$retryTime} seconds."); - sleep($retryTime); - - // Try again - $this->run(); - } else { - // Log that we've exhausted all retries - error_log("Max retries reached for task {$this->name}. Task will not be retried."); - } - } - - private function scheduleNextRun() - { - // You can schedule the next run based on cron expression or your custom logic - $this->nextRunTime = $this->calculateNextRunTime(); - } - - private function calculateNextRunTime() + /** + * Calculate the next run time based on the cron expression + * + * @return \DateTime + */ + public function calculateNextRunTime() { // Ensure the cron expression is valid if (empty($this->expression)) { throw new \InvalidArgumentException("Cron expression must be set."); } - + // Split the cron expression into parts $parts = preg_split('/\s+/', $this->expression); if (count($parts) !== 5) { throw new \InvalidArgumentException("Invalid cron expression: {$this->expression}"); } - - // Extract the cron fields + + // Extract cron fields list($minuteField, $hourField, $dayOfMonthField, $monthField, $dayOfWeekField) = $parts; - + + // Initialize current time and timezone $now = new \DateTime('now', new \DateTimeZone($this->timezone)); $next = clone $now; - - // Calculate next minute - $nextMinute = $this->getNextFieldValue($next->format('i'), $minuteField, 0, 59); - - if ($nextMinute !== null) { - - $next->setTime($next->format('H'), $nextMinute); - } else { + + // Only increment the minute by default, assuming the task is set to run every minute + if ($minuteField === '*' && $hourField === '*' && $dayOfMonthField === '*' && $monthField === '*' && $dayOfWeekField === '*') { + $next->modify('+1 minute'); + return $next; + } + + // Calculate the next minute + $nextMinute = $this->getNextFieldValue((int)$next->format('i'), $minuteField, 0, 59); + if ($nextMinute < (int)$next->format('i')) { + // Increment the hour if the calculated minute is in the past for the current hour $next->modify('+1 hour'); - $next->setTime(0, $this->getNextFieldValue(0, $minuteField, 0, 59)); } - - // Calculate next hour - $nextHour = $this->getNextFieldValue($next->format('H'), $hourField, 0, 23); - if ($nextHour !== null) { - $next->setTime($nextHour, $next->format('i')); - } else { + $next->setTime((int)$next->format('H'), $nextMinute); + + // Calculate the next hour + $nextHour = $this->getNextFieldValue((int)$next->format('H'), $hourField, 0, 23); + if ($nextHour < (int)$next->format('H')) { + // Increment the day if the calculated hour is in the past for the current day $next->modify('+1 day'); - $next->setTime(0, $this->getNextFieldValue(0, $minuteField, 0, 59)); } - - // Calculate next day of the month - $nextDay = $this->getNextFieldValue($next->format('d'), $dayOfMonthField, 1, 31); - if ($nextDay !== null) { - $next->setDate($next->format('Y'), $next->format('m'), $nextDay); - } else { + $next->setTime($nextHour, (int)$next->format('i')); + + // Calculate the next day of the month + $nextDay = $this->getNextFieldValue((int)$next->format('d'), $dayOfMonthField, 1, 31); + if ($nextDay < (int)$next->format('d')) { + // Increment the month if the calculated day is in the past for the current month $next->modify('+1 month'); - $next->setDate($next->format('Y'), $next->format('m'), $this->getNextFieldValue(1, $dayOfMonthField, 1, 31)); } - - // Calculate next month - $nextMonth = $this->getNextFieldValue($next->format('n'), $monthField, 1, 12); - if ($nextMonth !== null) { - $next->setDate($next->format('Y'), $nextMonth, $next->format('d')); - } else { + $next->setDate((int)$next->format('Y'), (int)$next->format('m'), $nextDay); + + // Calculate the next month + $nextMonth = $this->getNextFieldValue((int)$next->format('n'), $monthField, 1, 12); + if ($nextMonth < (int)$next->format('n')) { + // Increment the year if the calculated month is in the past for the current year $next->modify('+1 year'); - $next->setDate($next->format('Y'), $this->getNextFieldValue(1, $monthField, 1, 12), $next->format('d')); } + $next->setDate((int)$next->format('Y'), $nextMonth, (int)$next->format('d')); + + // Calculate the next day of the week if specified + if ($dayOfWeekField !== '*') { + $nextDayOfWeek = $this->getNextFieldValue((int)$next->format('w'), $dayOfWeekField, 0, 6); + while ((int)$next->format('w') !== $nextDayOfWeek) { + $next->modify('+1 day'); // Move forward by one day until it matches the specified day of the week + } + } + + return $next; + } + + /** + * Handle retries for the task + * + * @param \Exception $e + */ + private function handleRetry(\Exception $e) + { + if ($this->retryCount < $this->maxRetries) { + $this->retryCount++; + $retryTime = $this->retryInterval * $this->retryCount; - // Calculate next day of the week - $nextDayOfWeek = $this->getNextFieldValue($next->format('w'), $dayOfWeekField, 0, 6); + // Log the retry attempt + error_log("Retry attempt {$this->retryCount} for task {$this->name}, will retry in {$retryTime} seconds."); + sleep($retryTime); - if ($nextDayOfWeek !== null) { - while (intval($next->format('w')) !== $nextDayOfWeek) { - $next->modify('+1 day'); - } + // Try again + $this->run(); } else { - $next->modify('+1 week'); + // Log that we've exhausted all retries + error_log("Max retries reached for task {$this->name}. Task will not be retried."); } + } - return $next; + /** + * Schedule the next run time for the task + */ + private function scheduleNextRun() + { + // You can schedule the next run based on cron expression or your custom logic + $this->nextRunTime = $this->calculateNextRunTime(); } + /** + * Get the next valid field value + * + * @param int $currentValue + * @param string $field + * @param int $min + * @param int $max + * @return int + */ private function getNextFieldValue($currentValue, $field, $min, $max) { $values = []; diff --git a/services/Core/Scheduling/Hm_Scheduler.php b/services/Core/Scheduling/Hm_Scheduler.php index 5ed6120c3..d3292880b 100644 --- a/services/Core/Scheduling/Hm_Scheduler.php +++ b/services/Core/Scheduling/Hm_Scheduler.php @@ -2,10 +2,9 @@ namespace Services\Core\Scheduling; +use Hm_Msgs; use Hm_Cache; use Hm_Debug; -use Hm_Msgs; -use Hm_Session_Setup; use Services\Core\Hm_Container; class Hm_Scheduler @@ -13,11 +12,21 @@ class Hm_Scheduler protected $tasks = []; protected $config; + /** + * Hm_Scheduler constructor. + * @param $config + */ public function __construct($config) { $this->config = $config; } + /** + * Register a new command task with the given configuration. + * + * @param string $command + * @return Hm_CommandTask + */ public function command($command) { $cache = new Hm_Cache($this->config, Hm_Container::getContainer()->get('session')); @@ -54,6 +63,7 @@ public function run() foreach ($this->tasks as $task) { if ($task->isDue()) { try { + echo "Running Task '{$task->getName()}'\n"; $task->run(); Hm_Debug::add("Task '{$task->getName()}' executed successfully."); Hm_Msgs::add("Task '{$task->getName()}' executed successfully."); @@ -76,4 +86,14 @@ public function displayScheduledTasks() echo "Task Name: {$task->name}, Next Run Time: {$task->nextRunTime->format('Y-m-d H:i:s')}, Last Run Time: " . ($task->lastRunTime ? $task->lastRunTime->format('Y-m-d H:i:s') : 'Never') . "\n"; } } + + /** + * Get all scheduled tasks. + * + * @return array + */ + public function getTasks() + { + return $this->tasks; + } } diff --git a/services/Events/Hm_NewEmailProcessedEvent.php b/services/Events/Hm_NewEmailProcessedEvent.php index 029f110d7..9fd5ce6c8 100644 --- a/services/Events/Hm_NewEmailProcessedEvent.php +++ b/services/Events/Hm_NewEmailProcessedEvent.php @@ -7,7 +7,7 @@ class Hm_NewEmailProcessedEvent extends Hm_BaseEvent// implements Hm_ShouldQueue { - use Hm_Dispatchable;//, Hm_InteractsWithQueue; + use Hm_Dispatchable;//Hm_InteractsWithQueue; /** * Create a new event instance. diff --git a/services/Hm_ConsoleKernal.php b/services/Hm_ConsoleKernal.php deleted file mode 100644 index 383aa2db1..000000000 --- a/services/Hm_ConsoleKernal.php +++ /dev/null @@ -1,29 +0,0 @@ -scheduler = $scheduler; - - } - - /** - * Define the application's command schedule. - */ - public function schedule() - { - // Register tasks with the scheduler - $this->scheduler->command('check:mail') - ->everyMinute(); - // ->onOneServer() - // ->withoutOverlapping(10); - } -} diff --git a/services/Hm_ConsoleKernel.php b/services/Hm_ConsoleKernel.php index 5e2f20227..a9f9e21ed 100644 --- a/services/Hm_ConsoleKernel.php +++ b/services/Hm_ConsoleKernel.php @@ -3,12 +3,22 @@ namespace Services; use Services\Core\Scheduling\Hm_Scheduler; -use Services\Core\Hm_Container; +/** + * Class Hm_ConsoleKernel + * @package Services + */ class Hm_ConsoleKernel { + /** + * @var Hm_Scheduler + */ protected $scheduler; + /** + * Hm_ConsoleKernel constructor. + * @param Hm_Scheduler $scheduler + */ public function __construct(Hm_Scheduler $scheduler) { $this->scheduler = $scheduler; diff --git a/services/Hm_bootstrap.php b/services/Hm_bootstrap.php index 43b91b892..0faf8d099 100644 --- a/services/Hm_bootstrap.php +++ b/services/Hm_bootstrap.php @@ -1,7 +1,7 @@ [ Hm_NewMaiListener::class, ], ]; + /** + * Register the application's event listeners. + * + * @return void + */ public function register(): void { foreach ($this->listen as $event => $listeners) { diff --git a/services/Providers/Hm_QueueServiceProvider.php b/services/Providers/Hm_QueueServiceProvider.php index db44596c0..822af80ee 100644 --- a/services/Providers/Hm_QueueServiceProvider.php +++ b/services/Providers/Hm_QueueServiceProvider.php @@ -10,14 +10,25 @@ use Services\Core\Queue\Drivers\Hm_AmazonSQSQueue; use Symfony\Component\DependencyInjection\Reference; +/** + * Class Hm_QueueServiceProvider + * @package Services\Providers + */ class Hm_QueueServiceProvider { + /** + * @var Hm_QueueManager + */ protected Hm_QueueManager $queueManager; + /** + * Register the service provider + */ public function register() { - $queueConnection = getenv('QUEUE_DRIVER') ?: 'database'; $containerBuilder = Hm_Container::getContainer(); + $config = $containerBuilder->get('config'); + $queueConnection = $config->get('queue_driver'); $containerBuilder->register('queue.manager', Hm_QueueManager::class) ->setShared(true); @@ -46,7 +57,7 @@ public function register() $containerBuilder->getDefinition('queue.manager') ->addMethodCall('addDriver', ['sqs', new Reference('queue.driver.sqs')]); break; - default: + case 'database': $containerBuilder->register('queue.driver.database', Hm_DatabaseQueue::class) ->addArgument(new Reference('db')) ->addArgument(new Reference('db.connection')); diff --git a/services/Providers/Hm_SchedulerServiceProvider.php b/services/Providers/Hm_SchedulerServiceProvider.php index d0c201303..b9a219d78 100644 --- a/services/Providers/Hm_SchedulerServiceProvider.php +++ b/services/Providers/Hm_SchedulerServiceProvider.php @@ -4,9 +4,13 @@ use Hm_Cache; use Services\Core\Hm_Container; -use Services\Core\Scheduling\Hm_CacheMutex; use Services\Core\Scheduling\Hm_Scheduler; +use Services\Core\Scheduling\Hm_CacheMutex; +/** + * Class Hm_SchedulerServiceProvider + * @package Services\Providers + */ class Hm_SchedulerServiceProvider { diff --git a/services/readme.rd b/services/readme.rd index f98c47b02..55c86e8c7 100644 --- a/services/readme.rd +++ b/services/readme.rd @@ -15,17 +15,10 @@ $worker = new QueueWorker($queueManager->getDriver('redis')); $worker->work(); ``` +#Adding scheduler +you can use register or command on `$scheduler`, we prepared the class `Hm_ConsoleKernel` for that: ``` register(function () { echo "Running database cleanup\n"; @@ -40,16 +33,22 @@ $scheduler->command('backup:database')->dailyAt('02:00'); as we now have `Hm_SchedulerRunCommand.php` we can do: ``` -* * * * * php81 /path/to/cypht/project/console schedule:run +* * * * * cd /path-to-your-project && php console schedule:run >> /dev/null 2>&1 ``` +#Running the Scheduler Locally +Typically, you would not add a scheduler cron entry to your local development machine. Instead, you may use the `schedule:work` Console command. This command will run in the foreground and invoke the scheduler every minute until you terminate the command: ``` -// Dispatch the event -(new NewEmailProcessedEvent)->dispatch('user@example.com'); +php console schedule:work ``` + +#Dispatch the event +``` +(new NewEmailProcessedEvent)->dispatch('user@example.com'); ``` -// Notification Example usage +#Notification Example usage +``` use Services\Notifications\UserNotification; // Configure the notification channels