Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 16
0.00% covered (danger)
0.00%
0 / 2
CRAP
0.00% covered (danger)
0.00%
0 / 1
ParallelExecutor
0.00% covered (danger)
0.00%
0 / 16
0.00% covered (danger)
0.00%
0 / 2
42
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 runInParallel
0.00% covered (danger)
0.00%
0 / 15
0.00% covered (danger)
0.00%
0 / 1
30
1<?php
2declare( strict_types = 1 );
3
4namespace MediaWiki\Extension\Translate\Utilities;
5
6use MediaWiki\MediaWikiServices;
7
8/**
9 * Helper class for maintenance scripts to run things in parallel.
10 *
11 * See also ForkContoller and https://phabricator.wikimedia.org/T201970.
12 *
13 * @since 2020.11
14 * @license GPL-2.0-or-later
15 * @author Niklas Laxström
16 */
17class ParallelExecutor {
18    /** @var true[] */
19    private $pids = [];
20    /** @var int */
21    private $threads;
22
23    public function __construct( int $threads = 1 ) {
24        $this->threads = $threads;
25    }
26
27    public function runInParallel( callable $mainThread, callable $forkThread ): void {
28        // Fork to increase speed with parallelism. Also helps with memory usage if there are leaks.
29        $pid = -1;
30        if ( function_exists( 'pcntl_fork' ) ) {
31            $pid = pcntl_fork();
32        }
33
34        if ( $pid === 0 ) {
35            MediaWikiServices::resetChildProcessServices();
36            $forkThread();
37            exit();
38        } elseif ( $pid === -1 ) {
39            // Fork failed do it serialized
40            $forkThread();
41        } else {
42            // Main thread
43            $mainThread( $pid );
44            $this->pids[$pid] = true;
45
46            // If we hit the thread limit, wait for any child to finish.
47            if ( count( $this->pids ) >= $this->threads ) {
48                $status = 0;
49                $pid = pcntl_wait( $status );
50                unset( $this->pids[$pid] );
51            }
52        }
53    }
54}