Lines
100.00%
24 / 24
Methods
100.00%
5 / 5
Classes
100.00%
1 / 1
| Name | Lines | Methods | CRAP | ||||
|---|---|---|---|---|---|---|---|
| __construct | 100.00% | 1 / 1 | 100.00% | 1 / 1 | 1 | ||
| routeCommand | 100.00% | 9 / 9 | 100.00% | 1 / 1 | 4 | ||
| completeCommand | 100.00% | 9 / 9 | 100.00% | 1 / 1 | 3 | ||
| failCommandsOf | 100.00% | 3 / 3 | 100.00% | 1 / 1 | 2 | ||
| refuseCommand | 100.00% | 2 / 2 | 100.00% | 1 / 1 | 1 | ||
| 17 | final readonly class ExposureCommandRouter | |
| 18 | { | |
| 19 | public function __construct( | |
| 20 | private ExposureLink $exposures, | |
| 21 | private WorkerSlotRegistry $slots, | |
| 22 | private AppPauseRegistry $pauses, | |
| 23 | private PendingExposureCommands $pending, | |
| 24 | private AppMetrics $metrics, | |
| 25 | ) {} | |
| 26 | ||
| 27 | public function routeCommand(ExposedEntityCommand $command): void | |
| 28 | { | |
| 29 | if ($this->pauses->isPaused($command->appId)) { | |
| 30 | $this->refuseCommand($command, \sprintf('App %s is paused.', $command->appId)); | |
| 31 | ||
| 32 | return; | |
| 33 | } | |
| 34 | ||
| 35 | $handle = $command->owner === null ? null : $this->slots->findHandleForWorker($command->owner); | |
| 36 | ||
| 37 | if ($handle === null) { | |
| 38 | $this->refuseCommand($command, \sprintf('App %s is not running.', $command->appId)); | |
| 39 | ||
| 40 | return; | |
| 41 | } | |
| 42 | ||
| 43 | $this->pending->recordCommand($command); | |
| 44 | $handle->send(new ExposedEntityCommanded($command->commandId, ResourceScope::forApp($command->appId), $command->key, $command->command)); | |
| 45 | } | |
| 46 | ||
| 47 | public function completeCommand(WorkerHandle $handle, ExposedCommandAnswered $answer): void | |
| 48 | { | |
| 49 | $command = $this->pending->takeCommandAnsweredBy($answer->commandId, $handle->id); | |
| 50 | ||
| 51 | if ($command === null) { | |
| 52 | return; | |
| 53 | } | |
| 54 | ||
| 55 | if ($answer->accepted) { | |
| 56 | $this->metrics->recordExposedCommand($command->appId, ExposedCommandOutcome::Accepted); | |
| 57 | $this->exposures->acceptCommand($command); | |
| 58 | ||
| 59 | return; | |
| 60 | } | |
| 61 | ||
| 62 | $this->metrics->recordExposedCommand($command->appId, ExposedCommandOutcome::Rejected); | |
| 63 | $this->exposures->rejectCommand($command, $answer->rejection ?? \sprintf('App %s rejected the command.', $command->appId)); | |
| 64 | } | |
| 65 | ||
| 66 | public function failCommandsOf(WorkerId $workerId): void | |
| 67 | { | |
| 68 | foreach ($this->pending->takeCommandsOf($workerId) as $command) { | |
| 69 | $this->metrics->recordExposedCommand($command->appId, ExposedCommandOutcome::Lost); | |
| 70 | $this->exposures->rejectCommand($command, \sprintf('App %s stopped while handling the command.', $command->appId)); | |
| 71 | } | |
| 72 | } | |
| 73 | ||
| 74 | private function refuseCommand(ExposedEntityCommand $command, string $reason): void | |
| 75 | { | |
| 76 | $this->metrics->recordExposedCommand($command->appId, ExposedCommandOutcome::Refused); | |
| 77 | $this->exposures->rejectCommand($command, $reason); | |
| 78 | } | |
| 79 | } |