-
Notifications
You must be signed in to change notification settings - Fork 11.1k
/
ProcessDriver.php
93 lines (81 loc) · 2.66 KB
/
ProcessDriver.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
<?php
namespace Illuminate\Concurrency;
use Closure;
use Illuminate\Contracts\Concurrency\Driver;
use Illuminate\Foundation\Defer\DeferredCallback;
use Illuminate\Process\Factory as ProcessFactory;
use Illuminate\Process\Pool;
use Illuminate\Support\Arr;
use Laravel\SerializableClosure\SerializableClosure;
use Symfony\Component\Process\PhpExecutableFinder;
class ProcessDriver implements Driver
{
/**
* Create a new process based concurrency driver.
*/
public function __construct(protected ProcessFactory $processFactory)
{
//
}
/**
* Run the given tasks concurrently and return an array containing the results.
*/
public function run(Closure|array $tasks): array
{
$php = $this->phpBinary();
$artisan = $this->artisanBinary();
$results = $this->processFactory->pool(function (Pool $pool) use ($tasks, $php, $artisan) {
foreach (Arr::wrap($tasks) as $task) {
$pool->path(base_path())->env([
'LARAVEL_INVOKABLE_CLOSURE' => serialize(new SerializableClosure($task)),
])->command([
$php,
$artisan,
'invoke-serialized-closure',
]);
}
})->start()->wait();
return $results->collect()->map(function ($result) {
$result = json_decode($result->output(), true);
if (! $result['successful']) {
throw new $result['exception'](
$result['message']
);
}
return unserialize($result['result']);
})->all();
}
/**
* Start the given tasks in the background after the current task has finished.
*/
public function defer(Closure|array $tasks): DeferredCallback
{
$php = $this->phpBinary();
$artisan = $this->artisanBinary();
return defer(function () use ($tasks, $php, $artisan) {
foreach (Arr::wrap($tasks) as $task) {
$this->processFactory->path(base_path())->env([
'LARAVEL_INVOKABLE_CLOSURE' => serialize(new SerializableClosure($task)),
])->run([
$php,
$artisan,
'invoke-serialized-closure 2>&1 &',
]);
}
});
}
/**
* Get the PHP binary.
*/
protected function phpBinary(): string
{
return (new PhpExecutableFinder)->find(false) ?: 'php';
}
/**
* Get the Artisan binary.
*/
protected function artisanBinary(): string
{
return defined('ARTISAN_BINARY') ? ARTISAN_BINARY : 'artisan';
}
}