Completed
Push — master ( 58d870...e50603 )
by
unknown
02:12
created

Runner::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 4
rs 10
cc 1
nc 1
nop 2
1
<?php
2
/**
3
 * FullTextSearch - Full text search framework for Nextcloud
4
 *
5
 * This file is licensed under the Affero General Public License version 3 or
6
 * later. See the COPYING file.
7
 *
8
 * @author Maxence Lange <[email protected]>
9
 * @copyright 2018
10
 * @license GNU AGPL version 3 or any later version
11
 *
12
 * This program is free software: you can redistribute it and/or modify
13
 * it under the terms of the GNU Affero General Public License as
14
 * published by the Free Software Foundation, either version 3 of the
15
 * License, or (at your option) any later version.
16
 *
17
 * This program is distributed in the hope that it will be useful,
18
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20
 * GNU Affero General Public License for more details.
21
 *
22
 * You should have received a copy of the GNU Affero General Public License
23
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
24
 *  
25
 */
26
27
28
namespace OCA\FullTextSearch\Model;
29
30
use Exception;
31
use OCA\FullTextSearch\Exceptions\InterruptException;
32
use OCA\FullTextSearch\Exceptions\RunnerAlreadyUpException;
33
use OCA\FullTextSearch\Exceptions\TickDoesNotExistException;
34
use OCA\FullTextSearch\Exceptions\TickIsNotAliveException;
35
use OCA\FullTextSearch\Service\RunningService;
36
use Symfony\Component\Console\Output\OutputInterface;
37
38
39
class Runner {
40
41
42
	const TICK_TTL = 300;
43
	const TICK_MINIMUM = 2;
44
	const INFO_UPDATE = 10;
45
46
	/** @var RunningService */
47
	private $runningService;
48
49
	/** @var string */
50
	private $source;
51
52
	/** @var int */
53
	private $tickId;
54
55
	/** @var ExtendedBase */
56
	private $commandBase = null;
57
58
	/** @var OutputInterface */
59
	private $outputInterface = null;
60
61
	/** @var int */
62
	private $oldTick = 0;
63
64
	/** @var string */
65
	private $oldAction = '';
66
67
	/** @var int */
68
	private $ramTick = 0;
69
70
	/**
71
	 * Runner constructor.
72
	 *
73
	 * @param RunningService $runningService
74
	 * @param string $source
75
	 */
76
	public function __construct(RunningService $runningService, $source) {
77
		$this->runningService = $runningService;
78
		$this->source = $source;
79
	}
80
81
82
	/**
83
	 * @throws RunnerAlreadyUpException
84
	 * @throws Exception
85
	 */
86
	public function start() {
87
		$this->tickId = $this->runningService->start($this->source);
88
	}
89
90
91
	/**
92
	 * @param $action
93
	 *
94
	 * @throws InterruptException
95
	 * @throws TickDoesNotExistException
96
	 */
97
	public function update($action) {
98
99
		$tick = time();
100
		try {
101
			$this->hasBeenInterrupted();
102
		} catch (InterruptException $e) {
103
			$this->stop();
104
			throw $e;
105
		}
106
107
		if ($this->oldAction === $action && ($this->oldTick + self::TICK_MINIMUM > $tick)) {
108
			return;
109
		}
110
111
		try {
112
			$this->runningService->update($this->tickId, $action);
113
		} catch (TickIsNotAliveException $e) {
114
			$this->output('Force Quit');
115
			exit();
0 ignored issues
show
Coding Style Compatibility introduced by
The method update() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
116
		}
117
118
		$this->updateInfo($tick);
119
		$this->oldAction = $action;
120
		$this->oldTick = $tick;
121
	}
122
123
124
	/**
125
	 * @throws InterruptException
126
	 */
127
	private function hasBeenInterrupted() {
128
		if ($this->commandBase === null) {
129
			return;
130
		}
131
		$this->commandBase->hasBeenInterrupted();
132
	}
133
134
135
	/**
136
	 * @param $tick
137
	 */
138
	private function updateInfo($tick) {
139
		if (($this->ramTick + self::INFO_UPDATE) > $tick) {
140
			return;
141
		}
142
143
		$this->output('- RAM: ' . (memory_get_usage() / 1024 / 1024));
144
		$this->ramTick = $tick;
145
	}
146
147
148
	public function exception($reason, $stop) {
149
		if (!$stop) {
150
			$this->output('Exception: ' . $reason);
151
			// TODO: feed an array of exceptions for log;
152
		}
153
		$this->runningService->exception($this->tickId, $reason, $stop);
154
	}
155
156
157
	/**
158
	 * @throws TickDoesNotExistException
159
	 */
160
	public function stop() {
161
		$this->runningService->stop($this->tickId);
162
	}
163
164
165
	/**
166
	 * @param ExtendedBase $base
167
	 * @param OutputInterface $output
168
	 */
169
	public function sourceIsCommandLine(ExtendedBase $base, OutputInterface $output) {
170
		$this->outputInterface = $output;
171
		$this->commandBase = $base;
172
	}
173
174
175
	/**
176
	 * @param string $line
177
	 */
178
	public function output($line) {
179
		if ($this->outputInterface === null) {
180
			return;
181
		}
182
183
		$this->outputInterface->writeln($line);
184
	}
185
186
187
}