From 9b8e44cf601a7d79a621939e39a844f4ab8e0235 Mon Sep 17 00:00:00 2001 From: Uladzimir Tsykun Date: Sun, 26 Mar 2023 23:42:08 +0200 Subject: [PATCH] Added random delay to allows delaying cron trigger startups by random amount of seconds --- src/Symfony/Component/Scheduler/RecurringMessage.php | 4 ++-- .../Scheduler/Trigger/CronExpressionTrigger.php | 12 +++++++++--- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/Symfony/Component/Scheduler/RecurringMessage.php b/src/Symfony/Component/Scheduler/RecurringMessage.php index b4e9e0ce8947e..bdd3eb9b63c03 100644 --- a/src/Symfony/Component/Scheduler/RecurringMessage.php +++ b/src/Symfony/Component/Scheduler/RecurringMessage.php @@ -41,9 +41,9 @@ public static function every(string $frequency, object $message, string|\DateTim return new self(new DateIntervalTrigger($interval, $from, $until), $message); } - public static function cron(string $expression, object $message): self + public static function cron(string $expression, object $message, int $randomDelay = 0): self { - return new self(CronExpressionTrigger::fromSpec($expression), $message); + return new self(CronExpressionTrigger::fromSpec($expression, $randomDelay), $message); } public static function trigger(TriggerInterface $trigger, object $message): self diff --git a/src/Symfony/Component/Scheduler/Trigger/CronExpressionTrigger.php b/src/Symfony/Component/Scheduler/Trigger/CronExpressionTrigger.php index 5d9dba6d8f5b8..58905dfc70cfc 100644 --- a/src/Symfony/Component/Scheduler/Trigger/CronExpressionTrigger.php +++ b/src/Symfony/Component/Scheduler/Trigger/CronExpressionTrigger.php @@ -25,6 +25,7 @@ final class CronExpressionTrigger implements TriggerInterface, \Stringable { public function __construct( private readonly CronExpression $expression = new CronExpression('* * * * *'), + private readonly int $randomDelay = 0 ) { } @@ -33,17 +34,22 @@ public function __toString(): string return "cron: {$this->expression->getExpression()}"; } - public static function fromSpec(string $expression = '* * * * *'): self + public static function fromSpec(string $expression = '* * * * *', int $randomDelay = 0): self { if (!class_exists(CronExpression::class)) { throw new LogicException(sprintf('You cannot use "%s" as the "cron expression" package is not installed; try running "composer require dragonmantank/cron-expression".', __CLASS__)); } - return new self(new CronExpression($expression)); + return new self(new CronExpression($expression), $randomDelay); } public function getNextRunDate(\DateTimeImmutable $run): ?\DateTimeImmutable { - return \DateTimeImmutable::createFromMutable($this->expression->getNextRunDate($run)); + $nextRun = $this->expression->getNextRunDate($run); + if ($this->randomDelay > 0) { + $nextRun->add(new \DateInterval('PT'.random_int(0, $this->randomDelay).'S')); + } + + return \DateTimeImmutable::createFromMutable($nextRun); } }