Total Complexity | 54 |
Total Lines | 255 |
Duplicated Lines | 0 % |
Changes | 0 |
Complex classes like TCaptureForkLog 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.
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 TCaptureForkLog, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
47 | class TCaptureForkLog extends \Prado\Util\TBehavior |
||
48 | { |
||
49 | public const BEHAVIOR_NAME = 'captureforklog'; |
||
50 | |||
51 | /** @var bool Is the master receiver (of child logs) installed. */ |
||
52 | private bool $_receiverInstalled = false; |
||
53 | |||
54 | /** @var ?array The parent connections to each child fork receiving logs from. */ |
||
55 | protected ?array $_parentConnections = []; |
||
56 | |||
57 | /** @var mixed The child connection to the parent */ |
||
58 | protected mixed $_childConnection = null; |
||
59 | |||
60 | /** |
||
61 | * Installs {@see self::generateConnection()} on fxPrepareForFork and |
||
62 | * {@see self::configureForChildLogs()} on fxRestoreAfterFork. |
||
63 | * @return array Event callbacks for the behavior. |
||
64 | */ |
||
65 | public function events() |
||
66 | { |
||
67 | return [TProcessHelper::FX_PREPARE_FOR_FORK => 'generateConnection', |
||
68 | TProcessHelper::FX_RESTORE_AFTER_FORK => 'configureForChildLogs']; |
||
69 | } |
||
70 | |||
71 | /** |
||
72 | * |
||
73 | * @return ?float The priority of the behavior, default -10 and not |
||
74 | * the normal "null". |
||
75 | */ |
||
76 | public function getPriority(): ?float |
||
77 | { |
||
78 | if (($priority = parent::getPriority()) === null) { |
||
79 | $priority = -10; |
||
80 | } |
||
81 | return $priority; |
||
82 | } |
||
83 | |||
84 | /** |
||
85 | * This is the singleton behavior. Only one instance of itself can be a behavior |
||
86 | * of the owner. |
||
87 | * @param string $name The name of teh behavior being added to the owner. |
||
88 | * @param IBaseBehavior $behavior The behavior being added to the owner. |
||
89 | * @param TCallChain $chain The chain of event handlers. |
||
90 | */ |
||
91 | public function dyAttachBehavior($name, $behavior, TCallChain $chain) |
||
92 | { |
||
93 | $owner = $this->getOwner(); |
||
94 | if (count($owner->getBehaviors(self::class)) > 1) { |
||
95 | $owner->detachBehavior($name); |
||
96 | } |
||
97 | return $chain->dyAttachBehavior($name, $behavior); |
||
98 | } |
||
99 | |||
100 | /** |
||
101 | * The behavior callback for fxPrepareForFork that creates a socket pair connection |
||
102 | * between the parent process and child process before forking. |
||
103 | * @param mixed $sender The TApplication doing the fork. |
||
104 | * @param mixed $param The parameter of fxPrepareForFork. |
||
105 | * @return ?array Any data to be passed back to the restore function. |
||
106 | * eg. `return ['key', 'data'];` will be passed in the restore function as |
||
107 | * `['key' => 'data', 'pid' => ###, ...]`. |
||
108 | */ |
||
109 | public function generateConnection(mixed $sender, mixed $param) |
||
110 | { |
||
111 | $domain = TProcessHelper::isSystemWindows() ? AF_INET : AF_UNIX; |
||
112 | if (!socket_create_pair($domain, SOCK_STREAM, 0, $this->_childConnection)) { |
||
113 | $this->_childConnection = null; |
||
114 | return; |
||
115 | } |
||
116 | $this->_childConnection[0] = socket_export_stream($this->_childConnection[0]); |
||
117 | $this->_childConnection[1] = socket_export_stream($this->_childConnection[1]); |
||
118 | return null; |
||
119 | } |
||
120 | |||
121 | /** |
||
122 | * The behavior call back for fxRestoreAfterFork that cleans the log and resets |
||
123 | * the logger to send the log to the parent process. The Parent process stores |
||
124 | * the child stream and pid and installs the onEndRequest handler to receive the |
||
125 | * logs from the children forks. |
||
126 | * @param mixed $sender |
||
127 | * @param array $data the |
||
128 | */ |
||
129 | public function configureForChildLogs(mixed $sender, mixed $data) |
||
163 | } |
||
164 | } |
||
165 | } |
||
166 | |||
167 | /** |
||
168 | * Receives logs from children forked processes and merges the logs with the current |
||
169 | * application TLogger. |
||
170 | * @param ?int $pid The process ID to receive the logs from, default null for all. |
||
171 | * @param bool $wait Wait for results until complete, default true. When false, |
||
172 | * this will process the pending logs and not wait for further logs. |
||
173 | */ |
||
174 | public function receiveLogsFromChildren(?int $pid = null, bool $wait = true) |
||
244 | } |
||
245 | } |
||
246 | |||
247 | /** |
||
248 | * First, Receives any logs from the children. If this instance is a child fork |
||
249 | * then send the log to the parent process. If the call is final then the connection |
||
250 | * to the parent is shutdown. |
||
251 | * @param mixed $logger The TLogger that raised the onFlushLogs event. |
||
252 | * @param mixed $final Is this the last and final call. |
||
253 | */ |
||
254 | public function sendLogsToParent($logger, $final) |
||
302 | } |
||
303 | } |
||
305 |
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:For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths