Issues (11)

src/Chips/Forking.php (5 issues)

1
<?php
2
/**
3
 * Forking daemon
4
 * User: moyo
5
 * Date: 28/12/2017
6
 * Time: 11:17 AM
7
 */
8
9
namespace Carno\Process\Chips;
10
11
use Carno\Process\Master;
12
use Carno\Process\Piping;
13
use Carno\Process\Program;
14
use Carno\Process\Progress;
15
use Carno\Promise\Promise;
16
use Swoole\Process as SWProcess;
0 ignored issues
show
The type Swoole\Process was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
17
use Swoole\Server as SWServer;
0 ignored issues
show
The type Swoole\Server was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
18
use Closure;
19
use Throwable;
20
21
trait Forking
22
{
23
    /**
24
     * @var Piping
25
     */
26
    private $forked = null;
27
28
    /**
29
     * @var bool
30
     */
31
    private $started = false;
32
33
    /**
34
     * @var Closure[]
35
     */
36
    private $events = [];
37
38
    /**
39
     * @var SWProcess
40
     */
41
    private $process = null;
42
43
    /**
44
     * @var bool
45
     */
46
    private $exiting = false;
47
48
    /**
49
     * @param int $event
50
     * @param Closure ...$actions
51
     */
52
    final public function on(int $event, Closure ...$actions) : void
53
    {
54
        $this->events[$event] = $actions;
55
    }
56
57
    /**
58
     * @return SWProcess
59
     */
60
    final public function process() : ?SWProcess
61
    {
62
        return $this->process;
63
    }
64
65
    /**
66
     * @return bool
67
     */
68
    final public function started() : bool
69
    {
70
        return $this->started;
71
    }
72
73
    /**
74
     * startup new process
75
     * @param object $server
76
     */
77
    final public function startup(object $server = null) : void
78
    {
79
        $this->process = new SWProcess(function (SWProcess $process) {
80
            // set process name
81
            if ($this->name) {
82
                @$process->name(sprintf('[process] %s', $this->name));
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for name(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unhandled  annotation

82
                /** @scrutinizer ignore-unhandled */ @$process->name(sprintf('[process] %s', $this->name));

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
83
            }
84
85
            // progress notify
86
            Progress::started(getmypid(), $this->name);
87
88
            // start pipe reading
89
            $this->forked->reading();
90
91
            // trigger system startup
92
            $this->forked->bootstrap();
93
94
            // trigger event::program::started
95
            $this->action(Program::STARTED);
96
97
            // trigger user starting
98
            $this->starting();
0 ignored issues
show
It seems like starting() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

98
            $this->/** @scrutinizer ignore-call */ 
99
                   starting();
Loading history...
99
        });
100
101
        // running
102
        $server instanceof SWServer ? $server->addProcess($this->process) : Master::watch($this->process->start());
103
104
        // flag
105
        $this->started = true;
106
    }
107
108
    /**
109
     * shutdown process
110
     * @param int $sig
111
     */
112
    final public function shutdown(int $sig = 0) : void
113
    {
114
        // check exiting state
115
        if ($this->exiting) {
116
            return;
117
        }
118
119
        $this->exiting = true;
120
121
        // be wait
122
        $wait = Promise::deferred();
123
124
        // user-land stopping
125
        $this->stopping($wait);
0 ignored issues
show
It seems like stopping() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

125
        $this->/** @scrutinizer ignore-call */ 
126
               stopping($wait);
Loading history...
126
127
        // trigger event::program::stopped
128
        $this->action(Program::STOPPED);
129
130
        // waiting
131
        $wait->then(function () use ($sig) {
132
            $this->exited($sig);
133
        }, function (Throwable $e) use ($sig) {
134
            $this->exited($sig, $e);
135
        });
136
    }
137
138
    /**
139
     * @param int $sig
140
     * @param Throwable $e
141
     */
142
    final private function exited(int $sig = 0, Throwable $e = null) : void
143
    {
144
        Progress::exited(getmypid(), $sig, $e ? 1 : 0, $this->name);
145
146
        $this->process->exit();
147
    }
148
149
    /**
150
     * @param int $event
151
     */
152
    final private function action(int $event) : void
153
    {
154
        foreach ($this->events[$event] ?? [] as $program) {
155
            $program($this->forked);
156
        }
157
    }
158
}
159