Complex classes like Process often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use Process, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
11 | class Process |
||
12 | { |
||
13 | /** |
||
14 | * @var Runnable|callable |
||
15 | */ |
||
16 | protected $runnable; |
||
17 | |||
18 | /** |
||
19 | * @var int |
||
20 | */ |
||
21 | protected $pid = 0; |
||
22 | |||
23 | /** |
||
24 | * @var string custom process name |
||
25 | */ |
||
26 | protected $name = null; |
||
27 | |||
28 | /** |
||
29 | * @var bool if the process is started |
||
30 | */ |
||
31 | protected $started = false; |
||
32 | |||
33 | /** |
||
34 | * @var bool |
||
35 | */ |
||
36 | protected $running = false; |
||
37 | |||
38 | /** |
||
39 | * @var int the signal which made the process terminate |
||
40 | */ |
||
41 | protected $term_signal = null; |
||
42 | |||
43 | /** |
||
44 | * @var int the signal which made the process stop |
||
45 | */ |
||
46 | protected $stop_signal = null; |
||
47 | |||
48 | /** |
||
49 | * @var int error code |
||
50 | */ |
||
51 | protected $errno = null; |
||
52 | |||
53 | /** |
||
54 | * @var string error message |
||
55 | */ |
||
56 | protected $errmsg = null; |
||
57 | |||
58 | /** |
||
59 | * @var bool |
||
60 | */ |
||
61 | protected $if_signal = false; |
||
62 | |||
63 | /** |
||
64 | * @var array |
||
65 | */ |
||
66 | protected $callbacks = array(); |
||
67 | |||
68 | /** |
||
69 | * @var array signal handlers |
||
70 | */ |
||
71 | protected $signal_handlers = array(); |
||
72 | |||
73 | |||
74 | /** |
||
75 | * @param string $execution it can be a Runnable object, callback function or null |
||
76 | * @param null $name process name,you can manager the process by it's name. |
||
77 | */ |
||
78 | 60 | public function __construct($execution = null, $name = null) |
|
79 | { |
||
80 | 60 | if (!is_null($execution) && $execution instanceof Runnable) { |
|
81 | 9 | $this->runnable = $execution; |
|
82 | 60 | } elseif (!is_null($execution) && is_callable($execution)) { |
|
83 | 45 | $this->runnable = $execution; |
|
84 | 54 | } elseif (!is_null($execution)) { |
|
85 | throw new \InvalidArgumentException('param execution is not a object of Runnable or callable'); |
||
86 | } else { |
||
87 | 12 | Utils::checkOverwriteRunMethod(get_class($this)); |
|
88 | } |
||
89 | 57 | if (!is_null($name)) { |
|
90 | 3 | $this->name = $name; |
|
91 | 3 | } |
|
92 | |||
93 | 57 | $this->initStatus(); |
|
94 | 57 | } |
|
95 | |||
96 | /** |
||
97 | * init process status |
||
98 | */ |
||
99 | 57 | protected function initStatus() |
|
100 | { |
||
101 | 57 | $this->pid = null; |
|
102 | 57 | $this->running = null; |
|
103 | 57 | $this->term_signal = null; |
|
104 | 57 | $this->stop_signal = null; |
|
105 | 57 | $this->errno = null; |
|
106 | 57 | $this->errmsg = null; |
|
107 | 57 | } |
|
108 | |||
109 | /** |
||
110 | * get pid |
||
111 | * |
||
112 | * @return int |
||
113 | */ |
||
114 | 9 | public function getPid() |
|
118 | |||
119 | /** |
||
120 | * get or set name |
||
121 | * |
||
122 | * @param string|null $name |
||
123 | * @return mixed |
||
124 | */ |
||
125 | 3 | public function name($name = null) |
|
126 | { |
||
127 | 3 | if (!is_null($name)) { |
|
128 | $this->name = $name; |
||
129 | } else { |
||
130 | 3 | return $this->name; |
|
131 | } |
||
132 | } |
||
133 | |||
134 | /** |
||
135 | * if the process is stopped |
||
136 | * |
||
137 | * @return bool |
||
138 | */ |
||
139 | 3 | public function isStopped() |
|
147 | |||
148 | /** |
||
149 | * if the process is started |
||
150 | * |
||
151 | * @return bool |
||
152 | */ |
||
153 | 15 | public function isStarted() |
|
157 | |||
158 | /** |
||
159 | * get pcntl errno |
||
160 | * |
||
161 | * @return int |
||
162 | */ |
||
163 | 9 | public function errno() |
|
167 | |||
168 | /** |
||
169 | * get pcntl errmsg |
||
170 | * |
||
171 | * @return string |
||
172 | */ |
||
173 | 6 | public function errmsg() |
|
177 | |||
178 | 3 | public function ifSignal() |
|
182 | |||
183 | /** |
||
184 | * start the sub process |
||
185 | * and run the callback |
||
186 | * |
||
187 | * @return string pid |
||
188 | */ |
||
189 | 54 | public function start() |
|
214 | |||
215 | /** |
||
216 | * if the process is running |
||
217 | * |
||
218 | * @return bool |
||
219 | */ |
||
220 | 54 | public function isRunning() |
|
225 | |||
226 | /** |
||
227 | * update the process status |
||
228 | * |
||
229 | * @param bool $block |
||
230 | */ |
||
231 | 54 | protected function updateStatus($block = false) |
|
270 | |||
271 | /** |
||
272 | * get sub process callback |
||
273 | * |
||
274 | * @return array|callable|null |
||
275 | */ |
||
276 | 54 | protected function getCallable() |
|
289 | |||
290 | /** |
||
291 | * register signal SIGTERM handler, |
||
292 | * when the parent process call shutdown and use the default signal, |
||
293 | * this handler will be triggered |
||
294 | */ |
||
295 | protected function signal() |
||
301 | |||
302 | /** |
||
303 | * kill self |
||
304 | * |
||
305 | * @param bool|true $block |
||
306 | * @param int $signal |
||
307 | */ |
||
308 | 12 | public function shutdown($block = true, $signal = SIGTERM) |
|
322 | |||
323 | /** |
||
324 | * waiting for the sub process exit |
||
325 | * |
||
326 | * @param bool|true $block if block the process |
||
327 | * @param int $sleep default 0.1s check sub process status |
||
328 | * every $sleep milliseconds. |
||
329 | */ |
||
330 | 33 | public function wait($block = true, $sleep = 100000) |
|
342 | |||
343 | /** |
||
344 | * register sub process signal handler, |
||
345 | * when the sub process start, the handlers will be registered |
||
346 | * |
||
347 | * @param $signal |
||
348 | * @param callable $handler |
||
349 | */ |
||
350 | public function registerSignalHandler($signal, callable $handler) |
||
354 | |||
355 | /** |
||
356 | * after php-5.3.0, we can call pcntl_singal_dispatch to call signal handlers for pending signals |
||
357 | * which can save cpu resources than using declare(tick=n) |
||
358 | * |
||
359 | * @return bool |
||
360 | */ |
||
361 | public function dispatchSignal() |
||
365 | |||
366 | /** |
||
367 | * you should overwrite this function |
||
368 | * if you do not use the Runnable or callback. |
||
369 | */ |
||
370 | public function run() |
||
373 | } |
An exit expression should only be used in rare cases. For example, if you write a short command line script.
In most cases however, using an
exit
expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.