Lines 0.00% 0 / 27
Functions and Methods 0.00% 0 / 3
Classes and Traits 0.00% 0 / 1
Name Lines Functions and Methods CRAP Classes and Traits
PongBuilder 0.00% 0 / 27 0.00% 0 / 3 56 0.00% 0 / 1
 __construct 0.00% 0 / 1 0.00% 0 / 1 2
 buildPongFor 0.00% 0 / 13 0.00% 0 / 1 30
 buildActivityReport 0.00% 0 / 13 0.00% 0 / 1 2
1<?php
2
3declare(strict_types=1);
4
5namespace Stewart\Runtime\Worker;
6
7use Stewart\Contracts\Time\Clock;
8use Stewart\Runtime\Dispatch\LocalDispatcher;
9use Stewart\Runtime\Ipc\Message\AppActivityReport;
10use Stewart\Runtime\Ipc\Message\Ping;
11use Stewart\Runtime\Ipc\Message\Pong;
12use Stewart\Runtime\Lifecycle\AppState;
13use Stewart\Runtime\Model\ResourceScope;
14use Stewart\Runtime\Schedule\ScheduleRegistry;
15use Stewart\Store\GuardedStoreBackend;
16
17final readonly class PongBuilder
18{
19    public function __construct(
20        private AppLifecycle $apps,
21        private LocalDispatcher $dispatcher,
22        private ScheduleRegistry $schedules,
23        private AppActivityCounters $activityCounters,
24        private Clock $clock,
25        private ?GuardedStoreBackend $store = null,
26    ) {}
27
28    public function buildPongFor(Ping $ping): Pong
29    {
30        $reports = [];
31
32        foreach ($this->apps->listSlots() as $slot) {
33            $reports[] = $this->buildActivityReport($slot->scope(), $slot->state);
34        }
35
36        $shared = $this->buildActivityReport(ResourceScope::shared(), AppState::Running);
37
38        if ($shared->subscriptions > 0 || $shared->schedules > 0 || !$this->activityCounters->findOrCreateActivityForScope(ResourceScope::shared())->isIdle()) {
39            $reports[] = $shared;
40        }
41
42        return new Pong(
43            nonce: $ping->nonce,
44            loopLag: $this->clock->getNow()->elapsedSince($ping->sentAt),
45            memoryBytes: memory_get_usage(true),
46            apps: $reports,
47            store: $this->store?->getHealth(),
48        );
49    }
50
51    private function buildActivityReport(ResourceScope $scope, AppState $state): AppActivityReport
52    {
53        $activity = $this->activityCounters->findOrCreateActivityForScope($scope);
54
55        return new AppActivityReport(
56            scope: $scope,
57            state: $state,
58            subscriptions: $this->dispatcher->countFor($scope),
59            schedules: $this->schedules->countFor($scope),
60            delivered: $activity->delivered,
61            subscriptionDropped: $activity->dropped,
62            scheduleRuns: $activity->scheduleRuns,
63            publishes: $activity->publishes,
64            failures: $activity->failures,
65            suppressed: $activity->suppressed,
66        );
67    }
68}