1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Graze\ParallelProcess; |
4
|
|
|
|
5
|
|
|
use Symfony\Component\Process\Process; |
6
|
|
|
|
7
|
|
|
class Run implements RunInterface |
8
|
|
|
{ |
9
|
|
|
const ON_SUCCESS = 1; |
10
|
|
|
const ON_FAILURE = 2; |
11
|
|
|
const ON_PROGRESS = 3; |
12
|
|
|
|
13
|
|
|
/** @var Process */ |
14
|
|
|
private $process; |
15
|
|
|
/** @var callable|null */ |
16
|
|
|
private $onSuccess; |
17
|
|
|
/** @var callable|null */ |
18
|
|
|
private $onFailure; |
19
|
|
|
/** @var callable|null */ |
20
|
|
|
private $onProgress; |
21
|
|
|
/** @var float */ |
22
|
|
|
private $started; |
23
|
|
|
/** @var bool */ |
24
|
|
|
private $successful = false; |
25
|
|
|
/** @var bool */ |
26
|
|
|
private $completed = false; |
27
|
|
|
/** @var string */ |
28
|
|
|
private $last = ''; |
29
|
|
|
|
30
|
|
|
/** |
31
|
|
|
* Run constructor. |
32
|
|
|
* |
33
|
|
|
* @param Process $process |
34
|
|
|
* @param callable|null $onSuccess function (Process $process, float $duration, string $last) : void |
35
|
|
|
* @param callable|null $onFailure function (Process $process, float $duration, string $last) : void |
36
|
|
|
* @param callable|null $onProgress function (Process $process, float $duration, string $last) : void |
37
|
|
|
*/ |
38
|
|
View Code Duplication |
public function __construct( |
|
|
|
|
39
|
|
|
Process $process, |
40
|
|
|
callable $onSuccess = null, |
41
|
|
|
callable $onFailure = null, |
42
|
|
|
callable $onProgress = null |
43
|
|
|
) { |
44
|
|
|
$this->process = $process; |
45
|
|
|
$this->onSuccess = $onSuccess; |
46
|
|
|
$this->onFailure = $onFailure; |
47
|
|
|
$this->onProgress = $onProgress; |
48
|
|
|
} |
49
|
|
|
|
50
|
|
|
/** |
51
|
|
|
* Start the process |
52
|
|
|
* |
53
|
|
|
* @return $this |
54
|
|
|
*/ |
55
|
|
|
public function start() |
56
|
|
|
{ |
57
|
|
|
if (!$this->process->isRunning()) { |
58
|
|
|
$this->process->start(function ($type, $data) { |
59
|
|
|
$this->last = rtrim($data); |
60
|
|
|
}); |
61
|
|
|
$this->started = microtime(true); |
62
|
|
|
$this->completed = false; |
63
|
|
|
} |
64
|
|
|
|
65
|
|
|
return $this; |
66
|
|
|
} |
67
|
|
|
|
68
|
|
|
/** |
69
|
|
|
* Poll the process to see if it is still running, and trigger events |
70
|
|
|
* |
71
|
|
|
* @return bool true if the process is currently running (started and not terminated) |
72
|
|
|
*/ |
73
|
|
|
public function poll() |
74
|
|
|
{ |
75
|
|
|
if ($this->completed || !$this->hasStarted()) { |
76
|
|
|
return false; |
77
|
|
|
} |
78
|
|
|
|
79
|
|
|
if ($this->process->isRunning()) { |
80
|
|
|
$this->update($this->onProgress); |
81
|
|
|
return true; |
82
|
|
|
} |
83
|
|
|
|
84
|
|
|
$this->completed = true; |
85
|
|
|
|
86
|
|
|
if ($this->process->isSuccessful()) { |
87
|
|
|
$this->successful = true; |
88
|
|
|
$this->update($this->onSuccess); |
89
|
|
|
} else { |
90
|
|
|
$this->update($this->onFailure); |
91
|
|
|
} |
92
|
|
|
return false; |
93
|
|
|
} |
94
|
|
|
|
95
|
|
|
/** |
96
|
|
|
* Return if the underlying process is running |
97
|
|
|
* |
98
|
|
|
* @return bool |
99
|
|
|
*/ |
100
|
|
|
public function isRunning() |
101
|
|
|
{ |
102
|
|
|
return $this->process->isRunning(); |
103
|
|
|
} |
104
|
|
|
|
105
|
|
|
/** |
106
|
|
|
* Call an event callback |
107
|
|
|
* |
108
|
|
|
* @param callable|null $func |
109
|
|
|
*/ |
110
|
|
|
protected function update($func) |
111
|
|
|
{ |
112
|
|
|
if (!is_null($func)) { |
113
|
|
|
call_user_func( |
114
|
|
|
$func, |
115
|
|
|
$this->process, |
116
|
|
|
microtime(true) - $this->started, |
117
|
|
|
$this->last |
118
|
|
|
); |
119
|
|
|
} |
120
|
|
|
} |
121
|
|
|
|
122
|
|
|
/** |
123
|
|
|
* @return bool |
124
|
|
|
*/ |
125
|
|
|
public function isSuccessful() |
126
|
|
|
{ |
127
|
|
|
return $this->successful; |
128
|
|
|
} |
129
|
|
|
|
130
|
|
|
/** |
131
|
|
|
* @return bool |
132
|
|
|
*/ |
133
|
|
|
public function hasStarted() |
134
|
|
|
{ |
135
|
|
|
return $this->process->isStarted(); |
136
|
|
|
} |
137
|
|
|
|
138
|
|
|
/** |
139
|
|
|
* @return Process |
140
|
|
|
*/ |
141
|
|
|
public function getProcess() |
142
|
|
|
{ |
143
|
|
|
return $this->process; |
144
|
|
|
} |
145
|
|
|
} |
146
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.