Lines 100.00% 12 / 12
Functions and Methods 100.00% 10 / 10
Classes and Traits 100.00% 1 / 1
Name Lines Functions and Methods CRAP Classes and Traits
WorkerScheduler 100.00% 12 / 12 100.00% 10 / 10 10 100.00% 1 / 1
 __construct 100.00% 1 / 1 100.00% 1 / 1 1
 forApp 100.00% 1 / 1 100.00% 1 / 1 1
 runEvery 100.00% 1 / 1 100.00% 1 / 1 1
 runDailyAt 100.00% 1 / 1 100.00% 1 / 1 1
 runOnCron 100.00% 1 / 1 100.00% 1 / 1 1
 runAfter 100.00% 1 / 1 100.00% 1 / 1 1
 runAt 100.00% 1 / 1 100.00% 1 / 1 1
 runAtEntityTime 100.00% 3 / 3 100.00% 1 / 1 1
 runAtSunEvent 100.00% 1 / 1 100.00% 1 / 1 1
 armSchedule 100.00% 1 / 1 100.00% 1 / 1 1
1<?php
2
3declare(strict_types=1);
4
5namespace Stewart\Runtime\Schedule;
6
7use Closure;
8use DateTimeImmutable;
9use Psr\Log\LoggerInterface;
10use Stewart\Contracts\App\AppId;
11use Stewart\Contracts\Entity\EntityId;
12use Stewart\Contracts\Schedule\DayOfWeek;
13use Stewart\Contracts\Schedule\ScheduledTask;
14use Stewart\Contracts\Schedule\Scheduler;
15use Stewart\Contracts\Schedule\TimeOfDay;
16use Stewart\Contracts\Sun\SunCalendar;
17use Stewart\Contracts\Sun\SunEvent;
18use Stewart\Contracts\Time\Duration;
19use Stewart\Contracts\Time\SunOffset;
20use Stewart\Runtime\Model\ResourceScope;
21use Stewart\Support\Schedule\CalendarSchedule;
22use Stewart\Support\Schedule\CronSchedule;
23use Stewart\Support\Schedule\DelaySchedule;
24use Stewart\Support\Schedule\ElapsedSchedule;
25use Stewart\Support\Schedule\EntityTime;
26use Stewart\Support\Schedule\IntervalSchedule;
27use Stewart\Support\Schedule\OneShotSchedule;
28use Stewart\Support\Schedule\SunEventSchedule;
29use Stewart\Support\Schedule\WallClockSchedule;
30
31final readonly class WorkerScheduler implements Scheduler
32{
33    public function __construct(
34        private ScheduleRegistry $registry,
35        private SunCalendar $sunCalendar,
36        private EntityTimeScheduler $entityTimes,
37        private LoggerInterface $logger,
38        private ResourceScope $resourceScope,
39    ) {}
40
41    public function forApp(AppId $appId, LoggerInterface $logger): self
42    {
43        return new self($this->registry, $this->sunCalendar, $this->entityTimes, $logger, ResourceScope::forApp($appId));
44    }
45
46    public function runEvery(Duration $period, Closure $handler): ScheduledTask
47    {
48        return $this->armSchedule(IntervalSchedule::every($period), $handler);
49    }
50
51    public function runDailyAt(TimeOfDay|string $time, Closure $handler, DayOfWeek ...$onlyOn): ScheduledTask
52    {
53        return $this->armSchedule(CalendarSchedule::dailyAt($time, ...$onlyOn), $handler);
54    }
55
56    public function runOnCron(string $expression, Closure $handler): ScheduledTask
57    {
58        return $this->armSchedule(CronSchedule::parse($expression), $handler);
59    }
60
61    public function runAfter(Duration $delay, Closure $handler): ScheduledTask
62    {
63        return $this->armSchedule(DelaySchedule::after($delay), $handler);
64    }
65
66    public function runAt(DateTimeImmutable $moment, Closure $handler): ScheduledTask
67    {
68        return $this->armSchedule(OneShotSchedule::fromMoment($moment), $handler);
69    }
70
71    public function runAtEntityTime(EntityId|string $entity, Closure $handler): ScheduledTask
72    {
73        $entityId = EntityId::fromStringOrId($entity);
74        EntityTime::requireSupportedEntity($entityId);
75
76        return $this->entityTimes->armForEntity($this->resourceScope, $this->logger, $entityId, $handler);
77    }
78
79    public function runAtSunEvent(SunEvent $event, Closure $handler, ?SunOffset $offset = null): ScheduledTask
80    {
81        return $this->armSchedule(SunEventSchedule::forEvent($this->sunCalendar, $event, $offset), $handler);
82    }
83
84    private function armSchedule(WallClockSchedule|ElapsedSchedule $schedule, Closure $handler): ScheduledTask
85    {
86        return $this->registry->arm($this->resourceScope, $schedule, $this->logger, $handler);
87    }
88}