Code Coverage |
||||||||||
Classes and Traits |
Functions and Methods |
Lines |
||||||||
| Total | |
100.00% |
1 / 1 |
|
100.00% |
9 / 9 |
CRAP | |
100.00% |
50 / 50 |
| Factory | |
100.00% |
1 / 1 |
|
100.00% |
9 / 9 |
17 | |
100.00% |
50 / 50 |
| __construct | |
100.00% |
1 / 1 |
1 | |
100.00% |
5 / 5 |
|||
| addEnvs | |
100.00% |
1 / 1 |
1 | |
100.00% |
2 / 2 |
|||
| throwExceptionsOnFailure | |
100.00% |
1 / 1 |
1 | |
100.00% |
2 / 2 |
|||
| addProcess | |
100.00% |
1 / 1 |
1 | |
100.00% |
4 / 4 |
|||
| run | |
100.00% |
1 / 1 |
1 | |
100.00% |
4 / 4 |
|||
| start | |
100.00% |
1 / 1 |
1 | |
100.00% |
4 / 4 |
|||
| startDetached | |
100.00% |
1 / 1 |
1 | |
100.00% |
3 / 3 |
|||
| getProcessInfos | |
100.00% |
1 / 1 |
2 | |
100.00% |
5 / 5 |
|||
| launch | |
100.00% |
1 / 1 |
8 | |
100.00% |
21 / 21 |
|||
| 1 | <?php |
| 2 | |
| 3 | namespace Qmp\Laravel\AsyncProcessFactory; |
| 4 | |
| 5 | use Illuminate\Support\Collection; |
| 6 | use Illuminate\Support\Facades\Log; |
| 7 | use Qmp\Laravel\AsyncProcessFactory\Exceptions\SubProcessException; |
| 8 | |
| 9 | class Factory |
| 10 | { |
| 11 | /** |
| 12 | * The process stack collection |
| 13 | * |
| 14 | * @var Illuminate\Support\Collection |
| 15 | */ |
| 16 | protected $processStack; |
| 17 | |
| 18 | /** |
| 19 | * The artisan command for all the processes in the factory |
| 20 | * |
| 21 | * @param string $command |
| 22 | */ |
| 23 | protected $command; |
| 24 | |
| 25 | /** |
| 26 | * The default callback |
| 27 | * |
| 28 | * @var callable |
| 29 | */ |
| 30 | protected $callBack = null; |
| 31 | |
| 32 | /** |
| 33 | * Run or start |
| 34 | * |
| 35 | * @var string |
| 36 | */ |
| 37 | protected $launchType = null; |
| 38 | |
| 39 | /** |
| 40 | * The process stack infos |
| 41 | * |
| 42 | * @var Illuminate\Support\Collection |
| 43 | */ |
| 44 | protected $processInfos; |
| 45 | |
| 46 | /** |
| 47 | * Envs vars |
| 48 | * |
| 49 | * @var Collection |
| 50 | */ |
| 51 | protected $envs; |
| 52 | |
| 53 | /** |
| 54 | * If process fail, throw exception |
| 55 | * |
| 56 | * @var boolean |
| 57 | */ |
| 58 | protected $throw = false; |
| 59 | |
| 60 | /** |
| 61 | * Create a new process factory |
| 62 | * |
| 63 | * @param string $command |
| 64 | */ |
| 65 | public function __construct(string $command) |
| 66 | { |
| 67 | $this->processStack = collect([]); |
| 68 | $this->processInfos = collect([]); |
| 69 | $this->command = $command; |
| 70 | $this->envs = collect([]); |
| 71 | } |
| 72 | |
| 73 | /** |
| 74 | * Undocumented function |
| 75 | * |
| 76 | * @param array $envs |
| 77 | * @return void |
| 78 | */ |
| 79 | public function addEnvs(array $envs) |
| 80 | { |
| 81 | $this->envs = $this->envs->merge($envs); |
| 82 | } |
| 83 | |
| 84 | /** |
| 85 | * Undocumented function |
| 86 | * |
| 87 | * @param boolean $trhow |
| 88 | * @return void |
| 89 | */ |
| 90 | public function throwExceptionsOnFailure($throw = true) |
| 91 | { |
| 92 | $this->throw = $throw; |
| 93 | } |
| 94 | |
| 95 | /** |
| 96 | * Add a process to the stack |
| 97 | * |
| 98 | * @param array $options |
| 99 | * @return void |
| 100 | */ |
| 101 | public function addProcess(array $options = []): void |
| 102 | { |
| 103 | $process = new ProcessHandler($this->command); |
| 104 | $process->addOptions($options); |
| 105 | |
| 106 | $this->processStack->put($process->getkey(), $process); |
| 107 | } |
| 108 | |
| 109 | /** |
| 110 | * Start processes one by one |
| 111 | * |
| 112 | * @param callable $callback |
| 113 | * @return void |
| 114 | */ |
| 115 | public function run(callable $callback = null): void |
| 116 | { |
| 117 | $this->callBack = $callback; |
| 118 | $this->launchType = 'run'; |
| 119 | $this->launch(); |
| 120 | } |
| 121 | |
| 122 | /** |
| 123 | * Start Processes in parralel |
| 124 | * |
| 125 | * @param callable $callback |
| 126 | * @return void |
| 127 | */ |
| 128 | public function start(callable $callback = null): void |
| 129 | { |
| 130 | $this->callBack = $callback; |
| 131 | $this->launchType = 'start'; |
| 132 | $this->launch(); |
| 133 | } |
| 134 | |
| 135 | /** |
| 136 | * Start Processes in parralel and detached |
| 137 | * |
| 138 | * @param callable $callback |
| 139 | * @return void |
| 140 | */ |
| 141 | public function startDetached(): void |
| 142 | { |
| 143 | $this->launchType = 'startDetached'; |
| 144 | $this->launch(); |
| 145 | } |
| 146 | |
| 147 | /** |
| 148 | * Start Processes in parralel |
| 149 | * |
| 150 | * @param callable $callback |
| 151 | * @return Illuminate\Support\Collection |
| 152 | */ |
| 153 | public function getProcessInfos(callable $closure = null): Collection |
| 154 | { |
| 155 | if ($closure) { |
| 156 | return $this->processInfos->mapWithKeys(function ($process) use ($closure) { |
| 157 | return [$closure($process->get('options')) => $process]; |
| 158 | }); |
| 159 | } |
| 160 | |
| 161 | return $this->processInfos; |
| 162 | } |
| 163 | |
| 164 | /** |
| 165 | * Launch process stack |
| 166 | * |
| 167 | * @return void |
| 168 | */ |
| 169 | protected function launch(): void |
| 170 | { |
| 171 | try { |
| 172 | $message = $this->launchType === 'startDetached' ? 'start detached from' : $this->launchType . ' in'; |
| 173 | |
| 174 | $this->processStack->each(function ($process, $key) use ($message) { |
| 175 | Log::debug("Process $message factory ! {task #$key}"); |
| 176 | if (!$process->isRunning()) { |
| 177 | $started = $process->setEnv($this->envs)->{$this->launchType}($this->callBack); |
| 178 | $this->processInfos->push($process->getInfos($started)); |
| 179 | } |
| 180 | }); |
| 181 | |
| 182 | if ($this->launchType !== 'startDetached') { |
| 183 | while ($this->processStack->count()) { |
| 184 | $this->processStack->each(function ($process, $key) { |
| 185 | if (!$process->isRunning()) { |
| 186 | $this->processStack->forget($key); |
| 187 | Log::debug("Process in factory is done ! {task #$key}"); |
| 188 | } |
| 189 | }); |
| 190 | } |
| 191 | } |
| 192 | } catch (SubProcessException $e) { |
| 193 | if ($this->throw) { |
| 194 | throw $e; |
| 195 | } else { |
| 196 | Log::debug("Process in factory fail ! {task #" . $e->getKey() . "}"); |
| 197 | $this->processStack->forget($e->getKey()); |
| 198 | $this->launch(); |
| 199 | } |
| 200 | } |
| 201 | } |
| 202 | } |