22
33namespace skrtdev \async ;
44
5- use Closure ;
65
76class Pool{
87
@@ -19,15 +18,14 @@ class Pool{
1918
2019 public function __construct (?int $ max_childs = null , bool $ kill_childs = true )
2120 {
22- if (!extension_loaded (" pcntl " )){
23- throw new MissingExtensionException (" PCNTL Extension is missing in your PHP build " );
21+ if (!extension_loaded (' pcntl ' )){
22+ throw new MissingExtensionException (' PCNTL Extension is missing in your PHP build ' );
2423 }
2524 $ this ->pid = getmypid ();
2625 $ this ->max_childs = $ max_childs ?? (self ::getCoresCount () ?? 1 ) * 10 ;
2726 $ this ->kill_childs = $ kill_childs ;
2827
29- register_tick_function ([$ this , "tick " ]);
30- #pcntl_signal(SIGCHLD, SIG_IGN); // ignores the SIGCHLD signal
28+ register_tick_function ([$ this , 'tick ' ]);
3129
3230 pcntl_async_signals (true );
3331
@@ -41,52 +39,33 @@ public function __construct(?int $max_childs = null, bool $kill_childs = true)
4139
4240 foreach ($ this ->childs as $ key => $ child ) {
4341 if ($ pid === $ child ){
44- self ::breakpoint (" removed child from signal handler " );
42+ self ::breakpoint (' removed child from signal handler ' );
4543 unset($ this ->childs [$ key ]);
44+ break ;
4645 }
4746 }
4847 }
4948 });
5049 }
5150
52- public function checkChilds (): bool
53- {
54- return false ;
55- self ::breakpoint ("checkChilds() " );
56- $ removed = 0 ;
57- foreach ($ this ->childs as $ key => $ child ) {
58- if (!self ::isProcessRunning ($ child )){
59- unset($ this ->childs [$ key ]);
60- $ removed ++;
61- }
62- }
63- if ($ removed === 0 ){
64- self ::breakpoint ("CheckChilds didn't remove any child " );
65- return false ;
66- }
67- else {
68- self ::breakpoint ("CheckChilds removed $ removed childs " );
69- return true ;
70- };
71- }
7251
73- public function enqueue (Closure $ closure , string $ process_title = null , array $ args = []): void
52+ public function enqueue (callable $ callable , array $ args = []): void
7453 {
75- $ this ->queue [] = [$ closure , $ process_title , $ args ];
54+ $ this ->queue [] = [$ callable , $ args ];
7655 }
7756
78- protected function _parallel (Closure $ closure , string $ process_title = null , array $ args = [])
57+ protected function _parallel (callable $ callable , array $ args = [])
7958 {
80- self ::breakpoint (" started a parallel " );
81- self ::breakpoint (" parallel can be done: current childs: " .count ($ this ->childs )." / " .$ this ->max_childs );
59+ self ::breakpoint (' started a parallel ' );
60+ self ::breakpoint (' parallel can be done: current childs: ' .count ($ this ->childs ).' / ' .$ this ->max_childs );
8261 $ pid = pcntl_fork ();
8362 if ($ pid == -1 ) {
84- throw new CouldNotForkException (" Pool could not fork " );
63+ throw new CouldNotForkException (' Pool could not fork ' );
8564 }
8665 elseif ($ pid ){
8766 // we are the parent
8867 $ this ->childs [] = $ pid ;
89- self ::breakpoint (" child started " );
68+ self ::breakpoint (' child started ' );
9069 pcntl_wait ($ status , WNOHANG );
9170 }
9271 else {
@@ -95,63 +74,59 @@ protected function _parallel(Closure $closure, string $process_title = null, arr
9574 if (!$ this ->kill_childs ) {
9675 pcntl_signal (SIGINT , SIG_IGN );
9776 }
98- if (isset ($ process_title )){
99- @cli_set_process_title ($ process_title );
100- }
101- $ closure (...$ args );
77+ $ callable (...$ args );
10278 exit ;
10379 }
10480 }
10581
106- public function parallel (Closure $ closure , string $ process_title = null , ...$ args )
82+ public function parallel (callable $ callable , ...$ args )
10783 {
108- if (count ($ this ->childs ) > $ this ->max_childs /2 ){
109- #$this->checkChilds();
110- }
11184 if ($ this ->hasQueue ()){
112- self ::breakpoint (" resolving queue before parallel() " );
85+ self ::breakpoint (' resolving queue before parallel() ' );
11386 $ this ->resolveQueue ();
11487 if ($ this ->hasQueue ()){
115- self ::breakpoint (" enqueueing because there is a queue " );
116- return $ this ->enqueue ($ closure , $ process_title , $ args );
88+ self ::breakpoint (' enqueueing because there is a queue ' );
89+ return $ this ->enqueue ($ callable , $ args );
11790 }
11891 }
11992 elseif (count ($ this ->childs ) > $ this ->max_childs ){
120- self ::breakpoint ("enqueueing because of max reached (tried checkChilds but no results) " );
121- return $ this ->enqueue ($ closure , $ process_title , $ args );
93+ self ::breakpoint ('enqueueing because of max reached ' );
94+ return $ this ->enqueue ($ callable , $ args );
95+ }
96+ return $ this ->_parallel ($ callable , $ args );
97+ }
98+
99+ public function iterate (iterable $ iterable , callable $ callable ): void
100+ {
101+ foreach ($ iterable as $ value ) {
102+ $ this ->parallel ($ callable , $ value );
122103 }
123- return $ this ->_parallel ($ closure , $ process_title , $ args );
124104 }
125105
126106 public function resolveQueue (): void
127107 {
128108 if ($ this ->is_resolving_queue ) return ;
129109
130110 if (count ($ this ->childs ) >= $ this ->max_childs ){
131- self ::breakpoint ("resolveQueue() -> too many childs, trying to remove... " .PHP_EOL ."check childs from resolveQueue() " );
132- if (true || !$ this ->checkChilds ()){
133- self ::breakpoint ("resolveQueue() exited because of too many childs " );
134- return ;
135- }
111+ self ::breakpoint ('resolveQueue() exited because of too many childs ' );
112+ return ;
136113 }
137114
138115 $ this ->is_resolving_queue = true ;
139116
140- foreach ($ this ->queue as $ key => $ closure ) {
117+ foreach ($ this ->queue as $ key => $ callable ) {
141118 if (count ($ this ->childs ) < $ this ->max_childs ){
142119 unset($ this ->queue [$ key ]);
143120 self ::breakpoint ("resolveQueue() is resolving n. $ key " );
144- $ this ->_parallel (...$ closure );
121+ $ this ->_parallel (...$ callable );
145122 }
146123 else {
147- self ::breakpoint (" resolveQueue() can't resolve, too many childs " );
124+ self ::breakpoint (' resolveQueue() can \ 't resolve, too many childs ' );
148125 break ;
149- self ::breakpoint ("check childs from resolveQueue() " );
150- $ this ->checkChilds ();
151126 }
152127 }
153128 if (empty ($ this ->queue )){
154- self ::breakpoint (" queue is empty " );
129+ self ::breakpoint (' queue is empty ' );
155130 }
156131
157132 $ this ->is_resolving_queue = false ;
@@ -162,22 +137,16 @@ public function __destruct()
162137 {
163138 if ($ this ->is_parent ){
164139 $ this ->need_tick = false ;
165- self ::breakpoint (" triggered destructor " );
140+ self ::breakpoint (' triggered destructor ' );
166141 $ this ->wait ();
167142 }
168143 }
169144
170145 public static function getCoresCount (): ?int
171146 {
172- if (isset (self ::$ cores_count ) && self ::$ cores_count === 0 ) return null ;
147+ if (isset (self ::$ cores_count )) return self ::$ cores_count === 0 ? null : self ::$ cores_count ;
148+
173149
174- if (defined ('PHP_WINDOWS_VERSION_MAJOR ' )){
175- $ str = trim (shell_exec ('wmic cpu get NumberOfCores 2>&1 ' ));
176- if (!preg_match ('/(\d+)/ ' , $ str , $ matches )) {
177- $ cores_count = null ;
178- }
179- $ cores_count = (int ) $ matches [1 ];
180- }
181150 $ ret = @shell_exec ('nproc 2> /dev/null ' );
182151 if (is_string ($ ret )) {
183152 $ ret = trim ($ ret );
@@ -199,19 +168,12 @@ public static function getCoresCount(): ?int
199168
200169 public static function breakpoint ($ value ){
201170 return ;
202- usleep (5000 );
203171 print ($ value .PHP_EOL );
204172 }
205173
206- public static function isProcessRunning ($ pid ): bool
207- {
208- return posix_getpgid ($ pid ) !== false ;
209- }
210-
211174 public function tick ()
212175 {
213176 if ($ this ->is_parent && $ this ->need_tick && self ::$ last_tick !== time ()){
214- #print("tick".PHP_EOL);
215177 self ::$ last_tick = time ();
216178 if (!$ this ->is_resolving_queue ) $ this ->resolveQueue ();
217179 }
@@ -240,7 +202,7 @@ public function getChildsCount(): int
240202 public function waitQueue (): void
241203 {
242204 while ($ this ->hasQueue ()){
243- self ::breakpoint (" queue is not empty " );
205+ self ::breakpoint (' queue is not empty ' );
244206 $ this ->resolveQueue ();
245207 usleep (10000 );
246208 }
@@ -249,8 +211,7 @@ public function waitQueue(): void
249211 public function waitChilds (): void
250212 {
251213 while ($ this ->hasChilds ()){
252- self ::breakpoint ("there are still childs " );
253- #$this->checkChilds();
214+ self ::breakpoint ('there are still childs ' );
254215 usleep (10000 );
255216 }
256217 }
0 commit comments