Completed
Pull Request — master (#248)
by Fabien
02:43
created

ParallelProcessHandler::getResult()   A

Complexity

Conditions 4
Paths 6

Size

Total Lines 19
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 13
nc 6
nop 1
dl 0
loc 19
rs 9.8333
c 0
b 0
f 0
1
<?php declare(strict_types = 1);
2
3
namespace Churn\Process\Handler;
4
5
use Churn\File\File;
6
use Churn\Process\ChurnProcess;
7
use Churn\Process\Observer\OnSuccess;
8
use Churn\Process\ProcessFactory;
9
use Churn\Result\Result;
10
use function count;
11
use Generator;
12
13
class ParallelProcessHandler implements ProcessHandler
14
{
15
    /**
16
     * Array of completed processes.
17
     * @var array
18
     */
19
    private $completedProcesses;
20
21
    /**
22
     * Number of parallel jobs to run.
23
     * @var integer
24
     */
25
    private $numberOfParallelJobs;
26
27
    /**
28
     * ProcessManager constructor.
29
     * @param int $numberOfParallelJobs Number of parallel jobs to run.
30
     */
31
    public function __construct(int $numberOfParallelJobs)
32
    {
33
        $this->numberOfParallelJobs = $numberOfParallelJobs;
34
    }
35
36
    /**
37
     * Run the processes to gather information.
38
     * @param Generator      $filesFinder    Collection of files.
39
     * @param ProcessFactory $processFactory Process Factory.
40
     * @param OnSuccess      $onSuccess      The OnSuccess event observer.
41
     * @return void
42
     */
43
    public function process(
44
        Generator $filesFinder,
45
        ProcessFactory $processFactory,
46
        OnSuccess $onSuccess
47
    ): void {
48
        $pool = [];
49
        $this->completedProcesses = [];
50
        foreach ($filesFinder as $file) {
51
            while (count($pool) >= $this->numberOfParallelJobs) {
52
                $this->checkRunningProcesses($pool, $onSuccess);
53
            }
54
            $this->addToPool($pool, $file, $processFactory);
55
        }
56
        while (count($pool) > 0) {
57
            $this->checkRunningProcesses($pool, $onSuccess);
58
        }
59
    }
60
61
    /**
62
     * @param ChurnProcess[] $pool      Pool of processes.
63
     * @param OnSuccess      $onSuccess The OnSuccess event observer.
64
     * @return void
65
     */
66
    private function checkRunningProcesses(array &$pool, OnSuccess $onSuccess): void
67
    {
68
        foreach ($pool as $key => $process) {
69
            if ($process->isSuccessful()) {
70
                unset($pool[$key]);
71
                $this->sendEventIfComplete($this->getResult($process), $onSuccess);
72
            }
73
        }
74
    }
75
76
    /**
77
     * @param ChurnProcess[] $pool           Pool of processes.
78
     * @param File           $file           The file to process.
79
     * @param ProcessFactory $processFactory Process Factory.
80
     * @return void
81
     */
82
    private function addToPool(array &$pool, File $file, ProcessFactory $processFactory): void
83
    {
84
        $process = $processFactory->createGitCommitProcess($file);
85
        $process->start();
86
        $pool[$process->getKey()] = $process;
87
        $process = $processFactory->createCyclomaticComplexityProcess($file);
88
        $process->start();
89
        $pool[$process->getKey()] = $process;
90
    }
91
92
    /**
93
     * Returns the result of processes for a file.
94
     * @param ChurnProcess $process A successful process.
95
     * @return Result
96
     */
97
    private function getResult(ChurnProcess $process): Result
98
    {
99
        if (!isset($this->completedProcesses[$process->getFileName()])) {
100
            $this->completedProcesses[$process->getFileName()] = new Result($process->getFileName());
101
        }
102
        $result = $this->completedProcesses[$process->getFileName()];
103
        switch ($process->getType()) {
104
            case 'GitCommitProcess':
105
                $result->setCommits((int) $process->getOutput());
106
                break;
107
            case 'CyclomaticComplexityProcess':
108
                $result->setComplexity((int) $process->getOutput());
109
                break;
110
            default:
111
                // nothing to do
112
                break;
113
        }
114
115
        return $result;
116
    }
117
118
    /**
119
     * @param Result    $result    The result of the processes for a file.
120
     * @param OnSuccess $onSuccess The OnSuccess event observer.
121
     * @return void
122
     */
123
    private function sendEventIfComplete(Result $result, OnSuccess $onSuccess): void
124
    {
125
        if ($result->isComplete()) {
126
            unset($this->completedProcesses[$result->getFile()]);
127
            $onSuccess($result);
128
        }
129
    }
130
}
131