Passed
Pull Request — master (#248)
by Fabien
02:40
created

ParallelProcessHandler   A

Complexity

Total Complexity 15

Size/Duplication

Total Lines 124
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 41
dl 0
loc 124
rs 10
c 0
b 0
f 0
wmc 15

5 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 3 1
A process() 0 11 3
A doProcess() 0 17 5
A sendEventIfComplete() 0 4 2
A getResult() 0 19 4
1
<?php declare(strict_types = 1);
2
3
namespace Churn\Process\Handler;
4
5
use Churn\Collections\FileCollection;
6
use Churn\Process\ChurnProcess;
7
use Churn\Process\Observer\OnSuccess;
8
use Churn\Process\ProcessFactory;
9
use Churn\Result\Result;
10
use Illuminate\Support\Collection;
0 ignored issues
show
Bug introduced by
The type Illuminate\Support\Collection 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...
11
12
class ParallelProcessHandler implements ProcessHandler
13
{
14
    /**
15
     * Collection of running processes.
16
     * @var Collection
17
     */
18
    private $runningProcesses;
19
20
    /**
21
     * Collection of files.
22
     * @var FileCollection
23
     */
24
    private $filesCollection;
25
26
    /**
27
     * Array of completed processes.
28
     * @var array
29
     */
30
    private $completedProcessesArray;
31
32
    /**
33
     * Process Factory.
34
     * @var ProcessFactory
35
     */
36
    private $processFactory;
37
38
    /**
39
     * Number of parallel jobs to run.
40
     * @var integer
41
     */
42
    private $numberOfParallelJobs;
43
44
    /**
45
     * ProcessManager constructor.
46
     * @param int $numberOfParallelJobs Number of parallel jobs to run.
47
     */
48
    public function __construct(int $numberOfParallelJobs)
49
    {
50
        $this->numberOfParallelJobs = $numberOfParallelJobs;
51
    }
52
53
    /**
54
     * Run the processes to gather information.
55
     * @param FileCollection $filesCollection Collection of files.
56
     * @param ProcessFactory $processFactory  Process Factory.
57
     * @param OnSuccess      $onSuccess       The OnSuccess event observer.
58
     * @return void
59
     */
60
    public function process(
61
        FileCollection $filesCollection,
62
        ProcessFactory $processFactory,
63
        OnSuccess $onSuccess
64
    ): void {
65
        $this->filesCollection = $filesCollection;
66
        $this->processFactory = $processFactory;
67
        $this->runningProcesses = new Collection;
68
        $this->completedProcessesArray = [];
69
        while ($filesCollection->hasFiles() || $this->runningProcesses->count()) {
70
            $this->doProcess($this->numberOfParallelJobs, $onSuccess);
71
        }
72
    }
73
74
    /**
75
     * Process files in parallel.
76
     * @param integer   $numberOfParallelJobs Number of parallel jobs to run.
77
     * @param OnSuccess $onSuccess            The OnSuccess event observer.
78
     * @return void
79
     */
80
    private function doProcess(int $numberOfParallelJobs, OnSuccess $onSuccess): void
81
    {
82
        $index = $this->runningProcesses->count();
83
        for (; $index < $numberOfParallelJobs && $this->filesCollection->hasFiles() > 0; $index++) {
84
            $file = $this->filesCollection->getNextFile();
85
            $process = $this->processFactory->createGitCommitProcess($file);
86
            $process->start();
87
            $this->runningProcesses->put($process->getKey(), $process);
88
            $process = $this->processFactory->createCyclomaticComplexityProcess($file);
89
            $process->start();
90
            $this->runningProcesses->put($process->getKey(), $process);
91
        }
92
93
        foreach ($this->runningProcesses as $file => $process) {
94
            if ($process->isSuccessful()) {
95
                $this->runningProcesses->forget($process->getKey());
96
                $this->sendEventIfComplete($this->getResult($process), $onSuccess);
97
            }
98
        }
99
    }
100
101
    /**
102
     * Returns the result of processes for a file.
103
     * @param ChurnProcess $process A successful process.
104
     * @return Result
105
     */
106
    private function getResult(ChurnProcess $process): Result
107
    {
108
        if (!isset($this->completedProcessesArray[$process->getFileName()])) {
109
            $this->completedProcessesArray[$process->getFileName()] = new Result($process->getFileName());
110
        }
111
        $result = $this->completedProcessesArray[$process->getFileName()];
112
        switch ($process->getType()) {
113
            case 'GitCommitProcess':
114
                $result->setCommits((int) $process->getOutput());
115
                break;
116
            case 'CyclomaticComplexityProcess':
117
                $result->setComplexity((int) $process->getOutput());
118
                break;
119
            default:
120
                // nothing to do
121
                break;
122
        }
123
124
        return $result;
125
    }
126
127
    /**
128
     * @param Result    $result    The result of the processes for a file.
129
     * @param OnSuccess $onSuccess The OnSuccess event observer.
130
     * @return void
131
     */
132
    private function sendEventIfComplete(Result $result, OnSuccess $onSuccess): void
133
    {
134
        if ($result->isComplete()) {
135
            $onSuccess($result);
136
        }
137
    }
138
}
139