Lines
96.00%
48 / 50
Methods
81.81%
9 / 11
Classes
0.00%
0 / 1
| Name | Lines | Methods | CRAP | ||||
|---|---|---|---|---|---|---|---|
| __construct | 100.00% | 1 / 1 | 100.00% | 1 / 1 | 1 | ||
| forApp | 100.00% | 1 / 1 | 100.00% | 1 / 1 | 1 | ||
| forScope | 100.00% | 1 / 1 | 100.00% | 1 / 1 | 1 | ||
| buildMetricsKey | 100.00% | 1 / 1 | 100.00% | 1 / 1 | 2 | ||
| isSharedScope | 100.00% | 1 / 1 | 100.00% | 1 / 1 | 1 | ||
| recordActivityReport | 100.00% | 10 / 10 | 100.00% | 1 / 1 | 1 | ||
| recordCall | 100.00% | 1 / 1 | 100.00% | 1 / 1 | 1 | ||
| recordExposedCommand | 0.00% | 0 / 1 | 0.00% | 0 / 1 | 2 | ||
| recordLastFailure | 100.00% | 1 / 1 | 100.00% | 1 / 1 | 1 | ||
| buildAppStatus | 100.00% | 27 / 27 | 100.00% | 1 / 1 | 6 | ||
| buildExposedCommandStats | 80.00% | 4 / 5 | 0.00% | 0 / 1 | 3.07 | ||
| 24 | final class AppRunningTotals | |
| 25 | { | |
| 26 | private ?AppState $state = null; | |
| 27 | ||
| 28 | private ?Instant $reportedAt = null; | |
| 29 | ||
| 30 | private int $subscriptions = 0; | |
| 31 | ||
| 32 | private int $schedules = 0; | |
| 33 | ||
| 34 | private int $delivered = 0; | |
| 35 | ||
| 36 | private int $subscriptionDropped = 0; | |
| 37 | ||
| 38 | private int $scheduleRuns = 0; | |
| 39 | ||
| 40 | private int $publishes = 0; | |
| 41 | ||
| 42 | private int $failures = 0; | |
| 43 | ||
| 44 | private int $suppressed = 0; | |
| 45 | ||
| 46 | private ?FailureReport $lastFailure = null; | |
| 47 | ||
| 48 | /** @var array<string, ServiceCallStatsRecorder> */ | |
| 49 | private array $calls = []; | |
| 50 | ||
| 51 | /** @var array<string, int> */ | |
| 52 | private array $exposedCommandCounts = []; | |
| 53 | ||
| 54 | private function __construct( | |
| 55 | private readonly string $id, | |
| 56 | private readonly ?AppId $appId, | |
| 57 | private readonly string $class, | |
| 58 | private readonly ?WorkerId $workerId, | |
| 59 | ) {} | |
| 60 | ||
| 61 | public static function forApp(AppId $appId, string $class, ?WorkerId $workerId): self | |
| 62 | { | |
| 63 | return new self($appId->value, $appId, $class, $workerId); | |
| 64 | } | |
| 65 | ||
| 66 | public static function forScope(ResourceScope $scope, WorkerId $workerId): self | |
| 67 | { | |
| 68 | return new self($scope->wireValue(), $scope->appId, '', $workerId); | |
| 69 | } | |
| 70 | ||
| 71 | // The shared services.php scope exists once per worker, so its totals are kept per worker. | |
| 72 | public static function buildMetricsKey(ResourceScope $scope, WorkerId $workerId): string | |
| 73 | { | |
| 74 | return $scope->isShared() ? $scope->wireValue() . '#' . $workerId->value : $scope->wireValue(); | |
| 75 | } | |
| 76 | ||
| 77 | public function isSharedScope(): bool | |
| 78 | { | |
| 79 | return $this->appId === null; | |
| 80 | } | |
| 81 | ||
| 82 | public function recordActivityReport(AppActivityReport $report, ?AppActivityReport $previous, Instant $at): void | |
| 83 | { | |
| 84 | $this->state = $report->state; | |
| 85 | $this->reportedAt = $at; | |
| 86 | $this->subscriptions = $report->subscriptions; | |
| 87 | $this->schedules = $report->schedules; | |
| 88 | $this->delivered += max(0, $report->delivered - ($previous->delivered ?? 0)); | |
| 89 | $this->subscriptionDropped += max(0, $report->subscriptionDropped - ($previous->subscriptionDropped ?? 0)); | |
| 90 | $this->scheduleRuns += max(0, $report->scheduleRuns - ($previous->scheduleRuns ?? 0)); | |
| 91 | $this->publishes += max(0, $report->publishes - ($previous->publishes ?? 0)); | |
| 92 | $this->failures += max(0, $report->failures - ($previous->failures ?? 0)); | |
| 93 | $this->suppressed += max(0, $report->suppressed - ($previous->suppressed ?? 0)); | |
| 94 | } | |
| 95 | ||
| 96 | public function recordCall(ServiceCallOutcome $outcome, ?Duration $latency): void | |
| 97 | { | |
| 98 | ($this->calls[$outcome->value] ??= new ServiceCallStatsRecorder($outcome))->recordCall($latency); | |
| 99 | } | |
| 100 | ||
| 101 | public function recordExposedCommand(ExposedCommandOutcome $outcome): void | |
| 102 | { | |
| 103 | $this->exposedCommandCounts[$outcome->value] = ($this->exposedCommandCounts[$outcome->value] ?? 0) + 1; | |
| 104 | } | |
| 105 | ||
| 106 | public function recordLastFailure(FailureReport $failure): void | |
| 107 | { | |
| 108 | $this->lastFailure = $failure; | |
| 109 | } | |
| 110 | ||
| 111 | public function buildAppStatus(AppPauseRegistry $pausedApps, ExposureLink $exposures): AppStatus | |
| 112 | { | |
| 113 | $calls = $this->calls; | |
| 114 | ksort($calls); | |
| 115 | $pause = $this->appId === null ? null : $pausedApps->findPause($this->appId); | |
| 116 | $configPauseOverride = $this->appId === null ? null : $pausedApps->findConfigPauseOverride($this->appId); | |
| 117 | ||
| 118 | return new AppStatus( | |
| 119 | id: $this->id, | |
| 120 | class: $this->class, | |
| 121 | workerId: $this->workerId?->value, | |
| 122 | state: $this->state, | |
| 123 | pause: $pause === null ? null : new AppPauseStatus($pause->since, $pause->source), | |
| 124 | configPauseOverride: $configPauseOverride === null ? null : new AppPauseStatus($configPauseOverride->since, $configPauseOverride->source), | |
| 125 | reportedAt: $this->reportedAt, | |
| 126 | subscriptions: $this->subscriptions, | |
| 127 | schedules: $this->schedules, | |
| 128 | exposedEntities: $this->appId === null ? 0 : $exposures->countExposuresOfApp($this->appId), | |
| 129 | counters: new AppCounters( | |
| 130 | delivered: $this->delivered, | |
| 131 | subscriptionDropped: $this->subscriptionDropped, | |
| 132 | scheduleRuns: $this->scheduleRuns, | |
| 133 | publishes: $this->publishes, | |
| 134 | failures: $this->failures, | |
| 135 | suppressed: $this->suppressed, | |
| 136 | ), | |
| 137 | serviceCalls: array_values(array_map(static fn(ServiceCallStatsRecorder $recorder): ServiceCallStats => $recorder->buildServiceCallStats(), $calls)), | |
| 138 | lastFailure: $this->lastFailure, | |
| 139 | exposedCommands: $this->buildExposedCommandStats(), | |
| 140 | ); | |
| 141 | } | |
| 142 | ||
| 143 | /** @return list<ExposedCommandStats> */ | |
| 144 | private function buildExposedCommandStats(): array | |
| 145 | { | |
| 146 | $stats = []; | |
| 147 | ||
| 148 | foreach (ExposedCommandOutcome::cases() as $outcome) { | |
| 149 | if (isset($this->exposedCommandCounts[$outcome->value])) { | |
| 150 | $stats[] = new ExposedCommandStats($outcome, $this->exposedCommandCounts[$outcome->value]); | |
| 151 | } | |
| 152 | } | |
| 153 | ||
| 154 | return $stats; | |
| 155 | } | |
| 156 | } |