Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
11 / 11
100.00% covered (success)
100.00%
10 / 10
CRAP
100.00% covered (success)
100.00%
1 / 1
WorkerGroup
100.00% covered (success)
100.00%
11 / 11
100.00% covered (success)
100.00%
10 / 10
11
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
2
 getManager
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 all
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 get
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 wait
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 kill
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getRunning
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getStopped
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getIterator
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 count
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3declare(strict_types=1);
4
5/**
6 * This file is part of fast-forward/fork.
7 *
8 * This source file is subject to the license bundled
9 * with this source code in the file LICENSE.
10 *
11 * @copyright Copyright (c) 2026 Felipe SayĆ£o Lobato Abreu <github@mentordosnerds.com>
12 * @license   https://opensource.org/licenses/MIT MIT License
13 *
14 * @see       https://github.com/php-fast-forward/fork
15 * @see       https://github.com/php-fast-forward
16 * @see       https://datatracker.ietf.org/doc/html/rfc2119
17 */
18
19namespace FastForward\Fork\Worker;
20
21use ArrayIterator;
22use FastForward\Fork\Manager\ForkManagerInterface;
23use FastForward\Fork\Signal\Signal;
24use Traversable;
25
26use function array_filter;
27
28/**
29 * Provides an immutable view over a collection of workers created by the same manager.
30 *
31 * This class acts as a value object representing a group of workers and offers
32 * convenience methods for querying and interacting with them collectively.
33 *
34 * Instances of this class MUST be treated as immutable. Consumers SHOULD NOT
35 * attempt to modify the internal worker collection after instantiation.
36 */
37 class WorkerGroup implements WorkerGroupInterface
38{
39    /**
40     * Stores the workers tracked by this group.
41     *
42     * @var array<int, WorkerInterface>
43     */
44    private array $workers = [];
45
46    /**
47     * Initializes the worker group.
48     *
49     * @param ForkManagerInterface $manager manager that created the grouped workers
50     * @param WorkerInterface ...$workers Workers exposed through this immutable group.
51     */
52    public function __construct(
53        private  ForkManagerInterface $manager,
54        WorkerInterface ...$workers,
55    ) {
56        foreach ($workers as $worker) {
57            $this->workers[$worker->getPid()] = $worker;
58        }
59    }
60
61    /**
62     * {@inheritDoc}
63     */
64    public function getManager(): ForkManagerInterface
65    {
66        return $this->manager;
67    }
68
69    /**
70     * {@inheritDoc}
71     *
72     * @return array<int, WorkerInterface>
73     */
74    public function all(): array
75    {
76        return $this->workers;
77    }
78
79    /**
80     * {@inheritDoc}
81     */
82    public function get(int $pid): ?WorkerInterface
83    {
84        return $this->workers[$pid] ?? null;
85    }
86
87    /**
88     * {@inheritDoc}
89     */
90    public function wait(): void
91    {
92        $this->manager->wait($this);
93    }
94
95    /**
96     * {@inheritDoc}
97     */
98    public function kill(Signal $signal = Signal::Terminate): void
99    {
100        $this->manager->kill($signal, $this);
101    }
102
103    /**
104     * {@inheritDoc}
105     *
106     * @return array<int, WorkerInterface>
107     */
108    public function getRunning(): array
109    {
110        return array_filter($this->workers, static fn(WorkerInterface $worker): bool => $worker->isRunning());
111    }
112
113    /**
114     * {@inheritDoc}
115     *
116     * @return array<int, WorkerInterface>
117     */
118    public function getStopped(): array
119    {
120        return array_filter($this->workers, static fn(WorkerInterface $worker): bool => ! $worker->isRunning());
121    }
122
123    /**
124     * {@inheritDoc}
125     */
126    public function getIterator(): Traversable
127    {
128        return new ArrayIterator($this->workers);
129    }
130
131    /**
132     * {@inheritDoc}
133     */
134    public function count(): int
135    {
136        return \count($this->workers);
137    }
138}