Passed
Push — memory-limits ( 01808c...eb8c50 )
by Matias
05:43
created

CheckRequirementsTask::description()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 2
ccs 0
cts 2
cp 0
crap 2
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * @copyright Copyright (c) 2017, Matias De lellis <[email protected]>
4
 * @copyright Copyright (c) 2018, Branko Kokanovic <[email protected]>
5
 *
6
 * @author Branko Kokanovic <[email protected]>
7
 *
8
 * @license GNU AGPL version 3 or any later version
9
 *
10
 * This program is free software: you can redistribute it and/or modify
11
 * it under the terms of the GNU Affero General Public License as
12
 * published by the Free Software Foundation, either version 3 of the
13
 * License, or (at your option) any later version.
14
 *
15
 * This program is distributed in the hope that it will be useful,
16
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
 * GNU Affero General Public License for more details.
19
 *
20
 * You should have received a copy of the GNU Affero General Public License
21
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
22
 *
23
 */
24
namespace OCA\FaceRecognition\BackgroundJob\Tasks;
25
26
use OCP\IConfig;
27
28
use OCA\FaceRecognition\BackgroundJob\FaceRecognitionBackgroundTask;
29
use OCA\FaceRecognition\BackgroundJob\FaceRecognitionContext;
30
use OCA\FaceRecognition\Helper\MemoryLimits;
31
use OCA\FaceRecognition\Helper\Requirements;
32
use OCA\FaceRecognition\Migration\AddDefaultFaceModel;
33
34
/**
35
 * Check all requirements before we start engaging in lengthy background task.
36
 */
37
class CheckRequirementsTask extends FaceRecognitionBackgroundTask {
38
	/** @var IConfig Config */
39
	private $config;
40
41
	/**
42
	 * @param IConfig $config Config
43
	 */
44
	public function __construct(IConfig $config) {
45
		parent::__construct();
46
		$this->config = $config;
47
	}
48
49
	/**
50
	 * @inheritdoc
51
	 */
52
	public function description() {
53
		return "Check all requirements";
54
	}
55
56
	/**
57
	 * @inheritdoc
58
	 */
59
	public function execute(FaceRecognitionContext $context) {
60
		$this->setContext($context);
61
		$model = intval($this->config->getAppValue('facerecognition', 'model', AddDefaultFaceModel::DEFAULT_FACE_MODEL_ID));
62
63
		$req = new Requirements($context->appManager, $model);
64
65
		if (!$req->pdlibLoaded()) {
66
			$error_message = "PDLib is not loaded. Cannot continue";
67
			$this->logInfo($error_message);
68
			return false;
69
		}
70
71
		if (!$req->modelFilesPresent()) {
72
			$error_message =
73
				"Files of model with ID ' . $model . ' are not present in models/ directory.\n" .
74
				"Please contact administrator to change models you are using for face recognition\n" .
75
				"or reinstall application. File an issue here if that doesn\'t help: https://github.com/matiasdelellis/facerecognition/issues";
76
			$this->logInfo($error_message);
77
			return false;
78
		}
79
80
		// Determine the system memory with some considerations.
81
		$memoryAvailable = MemoryLimits::getAvailableMemory();
82
		if ($memoryAvailable <= 0) {
83
			// We cannot determine amount of memory to give to face recognition CNN.
84
			// We will hardcode it here to 1GB, but plan is to expose this to user in future.
85
			// TODO: allow user to choose "recognition quality", which will map to given memory.
86
			// If user explicitely set something, we ignore getting memory from system.
87
			$this->logDebug("Cannot detect amount of memory given to PHP process. Using 1GB for image processing");
88
			$memoryAvailable = 1024 * 1024 * 1024;
89
		}
90
91
		// Apply some prudent limits.
92
		if ($memoryAvailable < 1024 * 1024 * 1024) {
93
			$error_message =
94
				"\n" .
95
				"Seems that you have only " . intval($memoryAvailable / (1024 * 1024)). "MB of memory given to PHP.\n" .
96
				"Face recognition application requires at least 1 GB. You need to change your memory_limit in php.ini.\n" .
97
				"Check https://secure.php.net/manual/en/ini.core.php#ini.memory-limit for details.\n" .
98
				"If you already set this to unlimited, it seems your system is not having enough RAM memory.";
99
			$this->logInfo($error_message);
100
			return false;
101
		} else {
102
			$this->logDebug(sprintf('Found %d MB available to PHP.', $systemMemory / (1024 * 1024)));
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $systemMemory seems to be never defined.
Loading history...
103
			// No point going above 4GB ("4GB should be enough for everyone")
104
			if ($memoryAvailable > 4 * 1024 * 1024 * 1024) {
105
				$this->logDebug('Capping used memory to maximum of 4GB');
106
				$memoryAvailable = 4 * 1024 * 1024 * 1024;
107
			}
108
		}
109
110
		// Apply admin setting limit.
111
		$memorySetting = $this->config->getAppValue('facerecognition', 'memory-limits', '-1');
112
		if ($memorySetting > 0) {
113
			if ($memorySetting > $memoryAvailable) {
114
				$error_message =
115
					"\n" .
116
					"Seems that you configured" . intval($memorySetting / (1024 * 1024)) . " MB of memory, however, this exceeds" .
117
					"detected as maximum for PHP: " . intval($memoryAvailable / (1024 * 1024)). "MB.\n" .
118
					"We will ignore the FaceRecognition settings, and we will limit to that.";
119
				$this->logInfo($error_message);
120
			}
121
			else {
122
				$this->logInfo("Applying the memory limit to " . intval($memorySetting / (1024*1024)) . "MB configured in settings.");
123
				$memoryAvailable = $memorySetting;
124
			}
125
		}
126
127
		$context->propertyBag['memory'] = $memoryAvailable;
128
129
		return true;
130
	}
131
}