Passed
Push — Tests/ProcessService ( e68d69 )
by Tomas Norre
13:37 queued 03:31
created

ProcessService::getCrawlerCliPath()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 13
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 7
c 1
b 0
f 0
nc 2
nop 0
dl 0
loc 13
ccs 0
cts 10
cp 0
crap 6
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace AOE\Crawler\Service;
6
7
/***************************************************************
8
 *  Copyright notice
9
 *
10
 *  (c) 2017 AOE GmbH <[email protected]>
11
 *
12
 *  All rights reserved
13
 *
14
 *  This script is part of the TYPO3 project. The TYPO3 project is
15
 *  free software; you can redistribute it and/or modify
16
 *  it under the terms of the GNU General Public License as published by
17
 *  the Free Software Foundation; either version 3 of the License, or
18
 *  (at your option) any later version.
19
 *
20
 *  The GNU General Public License can be found at
21
 *  http://www.gnu.org/copyleft/gpl.html.
22
 *
23
 *  This script is distributed in the hope that it will be useful,
24
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
25
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
26
 *  GNU General Public License for more details.
27
 *
28
 *  This copyright notice MUST APPEAR in all copies of the script!
29
 ***************************************************************/
30
31
use AOE\Crawler\Configuration\ExtensionConfigurationProvider;
32
use AOE\Crawler\Controller\CrawlerController;
33
use AOE\Crawler\Domain\Repository\ProcessRepository;
34
use AOE\Crawler\Domain\Repository\QueueRepository;
35
use AOE\Crawler\Exception\ProcessException;
36
use AOE\Crawler\Utility\PhpBinaryUtility;
37
use TYPO3\CMS\Core\Compatibility\PublicMethodDeprecationTrait;
38
use TYPO3\CMS\Core\Compatibility\PublicPropertyDeprecationTrait;
39
use TYPO3\CMS\Core\Core\Environment;
40
use TYPO3\CMS\Core\Utility\CommandUtility;
41
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
42
use TYPO3\CMS\Core\Utility\GeneralUtility;
43
use TYPO3\CMS\Extbase\Object\ObjectManager;
44
45
/**
46
 * Class ProcessService
47
 *
48
 * @package AOE\Crawler\Service
49
 */
50
class ProcessService
51
{
52
    use PublicMethodDeprecationTrait;
53
    use PublicPropertyDeprecationTrait;
54
55
    /**
56
     * @var string[]
57
     * @noRector
58
     * @noRector \Rector\DeadCode\Rector\Property\RemoveUnusedPrivatePropertyRector
59
     * @noRector \Rector\DeadCode\Rector\Class_\RemoveSetterOnlyPropertyAndMethodCallRector
60
     */
61
    private $deprecatedPublicProperties = [
0 ignored issues
show
introduced by
The private property $deprecatedPublicProperties is not used, and could be removed.
Loading history...
62
        'queueRepository' => 'Using queueRepository is deprecated since 9.0.1 and will be removed in v11.x',
63
        'crawlerController' => 'Using crawlerController is deprecated since 9.0.1 and will be removed in v11.x',
64
        'countInARun' => 'Using countInARun is deprecated since 9.0.1 and will be removed in v11.x',
65
        'processLimit' => 'Using processLimit is deprecated since 9.0.1 and will be removed in v11.x',
66
        'verbose' => 'Using verbose is deprecated since 9.0.1 and will be removed in v11.x',
67
    ];
68
69
    /**
70
     * @var string[]
71
     * @noRector
72
     * @noRector \Rector\DeadCode\Rector\Property\RemoveUnusedPrivatePropertyRector
73
     * @noRector \Rector\DeadCode\Rector\Class_\RemoveSetterOnlyPropertyAndMethodCallRector
74
     */
75
    private $deprecatedPublicMethods = [
0 ignored issues
show
introduced by
The private property $deprecatedPublicMethods is not used, and could be removed.
Loading history...
76
        'multiProcess' => 'Using ProcessService::multiProcess() is deprecated since 9.0.1 and will be removed in v11.x',
77
        'reportItemStatus' => 'Using ProcessService::reportItemStatus() is deprecated since 9.0.1 and will be removed in v11.x',
78
        'startRequiredProcesses' => 'Using ProcessService::startRequiredProcesses() is deprecated since 9.0.1 and will be removed in v11.x',
79
    ];
80
81
    /**
82
     * @var int
83
     */
84
    private $timeToLive;
85
86
    /**
87
     * @var int
88
     * @deprecated
89
     */
90
    private $countInARun;
91
92
    /**
93
     * @var int
94
     * @deprecated
95
     */
96
    private $processLimit;
97
98
    /**
99
     * @var CrawlerController
100
     * @deprecated
101
     */
102
    private $crawlerController;
103
104
    /**
105
     * @var \AOE\Crawler\Domain\Repository\QueueRepository
106
     * @deprecated
107
     */
108
    private $queueRepository;
109
110
    /**
111
     * @var \AOE\Crawler\Domain\Repository\ProcessRepository
112
     */
113
    private $processRepository;
114
115
    /**
116
     * @var array
117
     */
118
    private $extensionSettings;
119
120
    /**
121
     * @var bool
122
     * @deprecated
123
     */
124
    private $verbose;
125
126
    /**
127
     * the constructor
128
     */
129
    public function __construct()
130
    {
131
        $objectManager = GeneralUtility::makeInstance(ObjectManager::class);
132
        $this->processRepository = $objectManager->get(ProcessRepository::class);
133
        $this->queueRepository = $objectManager->get(QueueRepository::class);
0 ignored issues
show
Deprecated Code introduced by
The property AOE\Crawler\Service\Proc...rvice::$queueRepository has been deprecated. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

133
        /** @scrutinizer ignore-deprecated */ $this->queueRepository = $objectManager->get(QueueRepository::class);
Loading history...
134
        $this->extensionSettings = GeneralUtility::makeInstance(ExtensionConfigurationProvider::class)->getExtensionConfiguration();
135
        $this->timeToLive = (int) $this->extensionSettings['processMaxRunTime'];
136
        $this->countInARun = (int) $this->extensionSettings['countInARun'];
0 ignored issues
show
Deprecated Code introduced by
The property AOE\Crawler\Service\ProcessService::$countInARun has been deprecated. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

136
        /** @scrutinizer ignore-deprecated */ $this->countInARun = (int) $this->extensionSettings['countInARun'];
Loading history...
137
        $this->processLimit = (int) $this->extensionSettings['processLimit'];
0 ignored issues
show
Deprecated Code introduced by
The property AOE\Crawler\Service\ProcessService::$processLimit has been deprecated. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

137
        /** @scrutinizer ignore-deprecated */ $this->processLimit = (int) $this->extensionSettings['processLimit'];
Loading history...
138
        $this->verbose = (bool) $this->extensionSettings['processVerbose'];
0 ignored issues
show
Deprecated Code introduced by
The property AOE\Crawler\Service\ProcessService::$verbose has been deprecated. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

138
        /** @scrutinizer ignore-deprecated */ $this->verbose = (bool) $this->extensionSettings['processVerbose'];
Loading history...
139
    }
140
141
    /**
142
     * starts multiple processes
143
     *
144
     * @param integer $timeout
145
     *
146
     * @throws \RuntimeException
147
     * @deprecated
148
     */
149
    public function multiProcess($timeout): void
150
    {
151
        if ($this->processLimit <= 1) {
0 ignored issues
show
Deprecated Code introduced by
The property AOE\Crawler\Service\ProcessService::$processLimit has been deprecated. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

151
        if (/** @scrutinizer ignore-deprecated */ $this->processLimit <= 1) {
Loading history...
152
            throw new \RuntimeException('To run crawler in multi process mode you have to configure the processLimit > 1.' . PHP_EOL);
153
        }
154
155
        $pendingItemsStart = $this->queueRepository->countAllPendingItems();
0 ignored issues
show
Deprecated Code introduced by
The property AOE\Crawler\Service\Proc...rvice::$queueRepository has been deprecated. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

155
        $pendingItemsStart = /** @scrutinizer ignore-deprecated */ $this->queueRepository->countAllPendingItems();
Loading history...
156
        $itemReportLimit = 20;
157
        $reportItemCount = $pendingItemsStart - $itemReportLimit;
158
        if ($this->verbose) {
0 ignored issues
show
Deprecated Code introduced by
The property AOE\Crawler\Service\ProcessService::$verbose has been deprecated. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

158
        if (/** @scrutinizer ignore-deprecated */ $this->verbose) {
Loading history...
159
            $this->reportItemStatus();
0 ignored issues
show
Deprecated Code introduced by
The function AOE\Crawler\Service\Proc...ice::reportItemStatus() has been deprecated. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

159
            /** @scrutinizer ignore-deprecated */ $this->reportItemStatus();
Loading history...
160
        }
161
        $this->startRequiredProcesses();
0 ignored issues
show
Deprecated Code introduced by
The function AOE\Crawler\Service\Proc...tartRequiredProcesses() has been deprecated. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

161
        /** @scrutinizer ignore-deprecated */ $this->startRequiredProcesses();
Loading history...
162
        $nextTimeOut = time() + $this->timeToLive;
163
        $currentPendingItems = '';
164
        for ($i = 0; $i < $timeout; $i++) {
165
            $currentPendingItems = $this->queueRepository->countAllPendingItems();
0 ignored issues
show
Deprecated Code introduced by
The property AOE\Crawler\Service\Proc...rvice::$queueRepository has been deprecated. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

165
            $currentPendingItems = /** @scrutinizer ignore-deprecated */ $this->queueRepository->countAllPendingItems();
Loading history...
166
            if ($this->startRequiredProcesses()) {
0 ignored issues
show
Deprecated Code introduced by
The function AOE\Crawler\Service\Proc...tartRequiredProcesses() has been deprecated. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

166
            if (/** @scrutinizer ignore-deprecated */ $this->startRequiredProcesses()) {
Loading history...
167
                $nextTimeOut = time() + $this->timeToLive;
168
            }
169
            if ($currentPendingItems === 0) {
170
                if ($this->verbose) {
0 ignored issues
show
Deprecated Code introduced by
The property AOE\Crawler\Service\ProcessService::$verbose has been deprecated. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

170
                if (/** @scrutinizer ignore-deprecated */ $this->verbose) {
Loading history...
171
                    echo 'Finished...' . chr(10);
172
                }
173
                break;
174
            }
175
            if ($currentPendingItems < $reportItemCount) {
176
                if ($this->verbose) {
0 ignored issues
show
Deprecated Code introduced by
The property AOE\Crawler\Service\ProcessService::$verbose has been deprecated. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

176
                if (/** @scrutinizer ignore-deprecated */ $this->verbose) {
Loading history...
177
                    $this->reportItemStatus();
0 ignored issues
show
Deprecated Code introduced by
The function AOE\Crawler\Service\Proc...ice::reportItemStatus() has been deprecated. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

177
                    /** @scrutinizer ignore-deprecated */ $this->reportItemStatus();
Loading history...
178
                }
179
                $reportItemCount = $currentPendingItems - $itemReportLimit;
180
            }
181
            sleep(1);
182
            if ($nextTimeOut < time()) {
183
                $timedOutProcesses = $this->processRepository->findAll();
184
                $nextTimeOut = time() + $this->timeToLive;
185
                if ($this->verbose) {
0 ignored issues
show
Deprecated Code introduced by
The property AOE\Crawler\Service\ProcessService::$verbose has been deprecated. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

185
                if (/** @scrutinizer ignore-deprecated */ $this->verbose) {
Loading history...
186
                    echo 'Cleanup' . implode(',', $timedOutProcesses->getProcessIds()) . chr(10);
187
                }
188
                $this->crawlerController->CLI_releaseProcesses($timedOutProcesses->getProcessIds());
0 ignored issues
show
Deprecated Code introduced by
The property AOE\Crawler\Service\Proc...ice::$crawlerController has been deprecated. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

188
                /** @scrutinizer ignore-deprecated */ $this->crawlerController->CLI_releaseProcesses($timedOutProcesses->getProcessIds());
Loading history...
189
            }
190
        }
191
        if ($currentPendingItems > 0 && $this->verbose) {
0 ignored issues
show
Deprecated Code introduced by
The property AOE\Crawler\Service\ProcessService::$verbose has been deprecated. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

191
        if ($currentPendingItems > 0 && /** @scrutinizer ignore-deprecated */ $this->verbose) {
Loading history...
192
            echo 'Stop with timeout' . chr(10);
193
        }
194
    }
195
196
    /**
197
     * starts new process
198
     * @throws ProcessException if no crawler process was started
199
     */
200
    public function startProcess(): bool
201
    {
202
        $ttl = (time() + $this->timeToLive - 1);
203
        $current = $this->processRepository->countNotTimeouted($ttl);
204
205
        // Check whether OS is Windows
206
        if (Environment::isWindows()) {
207
            $completePath = 'start ' . $this->getCrawlerCliPath();
208
        } else {
209
            $completePath = '(' . $this->getCrawlerCliPath() . ' &) > /dev/null';
210
        }
211
212
        $fileHandler = CommandUtility::exec($completePath);
213
        if ($fileHandler === false) {
214
            throw new ProcessException('could not start process!');
215
        }
216
        for ($i = 0; $i < 10; $i++) {
217
            if ($this->processRepository->countNotTimeouted($ttl) > $current) {
218
                return true;
219
            }
220
            sleep(1);
221
        }
222
        throw new ProcessException('Something went wrong: process did not appear within 10 seconds.');
223
    }
224
225
    /**
226
     * Returns the path to start the crawler from the command line
227
     */
228
    public function getCrawlerCliPath(): string
229
    {
230
        $phpPath = PhpBinaryUtility::getPhpBinary();
231
        $typo3BinaryPath = ExtensionManagementUtility::extPath('core') . 'bin/';
232
        $cliPart = 'typo3 crawler:processQueue';
233
        // Don't like the spacing, but don't have an better idea for now
234
        $scriptPath = $phpPath . ' ' . $typo3BinaryPath . $cliPart;
235
236
        if (Environment::isWindows()) {
237
            $scriptPath = str_replace('/', '\\', $scriptPath);
238
        }
239
240
        return ltrim($scriptPath);
241
    }
242
243
    /**
244
     * Reports curent Status of queue
245
     * @deprecated
246
     */
247
    protected function reportItemStatus(): void
248
    {
249
        echo 'Pending:' . $this->queueRepository->countAllPendingItems() . ' / Assigned:' . $this->queueRepository->countAllAssignedPendingItems() . chr(10);
0 ignored issues
show
Deprecated Code introduced by
The property AOE\Crawler\Service\Proc...rvice::$queueRepository has been deprecated. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

249
        echo 'Pending:' . /** @scrutinizer ignore-deprecated */ $this->queueRepository->countAllPendingItems() . ' / Assigned:' . $this->queueRepository->countAllAssignedPendingItems() . chr(10);
Loading history...
250
    }
251
252
    /**
253
     * according to the given count of pending items and the countInARun Setting this method
254
     * starts more crawling processes
255
     *
256
     * @return boolean if processes are started
257
     * @throws ProcessException
258
     * @deprecated
259
     */
260
    private function startRequiredProcesses()
261
    {
262
        $ret = false;
263
        $currentProcesses = $this->processRepository->countActive();
264
        $availableProcessesCount = $this->processLimit - $currentProcesses;
0 ignored issues
show
Deprecated Code introduced by
The property AOE\Crawler\Service\ProcessService::$processLimit has been deprecated. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

264
        $availableProcessesCount = /** @scrutinizer ignore-deprecated */ $this->processLimit - $currentProcesses;
Loading history...
265
        $requiredProcessesCount = ceil($this->queueRepository->countAllUnassignedPendingItems() / $this->countInARun);
0 ignored issues
show
Deprecated Code introduced by
The property AOE\Crawler\Service\ProcessService::$countInARun has been deprecated. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

265
        $requiredProcessesCount = ceil($this->queueRepository->countAllUnassignedPendingItems() / /** @scrutinizer ignore-deprecated */ $this->countInARun);
Loading history...
Deprecated Code introduced by
The property AOE\Crawler\Service\Proc...rvice::$queueRepository has been deprecated. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

265
        $requiredProcessesCount = ceil(/** @scrutinizer ignore-deprecated */ $this->queueRepository->countAllUnassignedPendingItems() / $this->countInARun);
Loading history...
266
        $startProcessCount = min([$availableProcessesCount, $requiredProcessesCount]);
267
        if ($startProcessCount <= 0) {
268
            return $ret;
269
        }
270
        if ($startProcessCount && $this->verbose) {
0 ignored issues
show
Deprecated Code introduced by
The property AOE\Crawler\Service\ProcessService::$verbose has been deprecated. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

270
        if ($startProcessCount && /** @scrutinizer ignore-deprecated */ $this->verbose) {
Loading history...
271
            echo 'Start ' . $startProcessCount . ' new processes (Running:' . $currentProcesses . ')';
272
        }
273
        for ($i = 0; $i < $startProcessCount; $i++) {
274
            usleep(100);
275
            if ($this->startProcess()) {
276
                if ($this->verbose) {
0 ignored issues
show
Deprecated Code introduced by
The property AOE\Crawler\Service\ProcessService::$verbose has been deprecated. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

276
                if (/** @scrutinizer ignore-deprecated */ $this->verbose) {
Loading history...
277
                    echo '.';
278
                    $ret = true;
279
                }
280
            }
281
        }
282
        if ($this->verbose) {
0 ignored issues
show
Deprecated Code introduced by
The property AOE\Crawler\Service\ProcessService::$verbose has been deprecated. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

282
        if (/** @scrutinizer ignore-deprecated */ $this->verbose) {
Loading history...
283
            echo chr(10);
284
        }
285
        return $ret;
286
    }
287
}
288