Completed
Pull Request — master (#93)
by Janis
14:36
created

RedisService::handleException()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 11
Code Lines 8

Duplication

Lines 11
Ratio 100 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
dl 11
loc 11
rs 9.4285
c 1
b 0
f 0
cc 2
eloc 8
nc 2
nop 1
1
<?php
2
3
/**
4
 * Nextcloud - OCR
5
 *
6
 * This file is licensed under the Affero General Public License version 3 or
7
 * later. See the COPYING file.
8
 *
9
 * @author Janis Koehr <[email protected]>
10
 * @copyright Janis Koehr 2017
11
 */
12
namespace OCA\Ocr\Service;
13
14
use Exception;
15
use OCA\Ocr\Db\OcrJob;
16
use OCA\Ocr\Db\OcrJobMapper;
17
use OCP\IConfig;
18
use OCP\IL10N;
19
use OCP\ILogger;
20
use OCA\Ocr\Constants\OcrConstants;
21
22
/**
23
 * Class RedisService
24
 *
25
 * @package OCA\Ocr\Service
26
 */
27
class RedisService {
28
	
29
	/**
30
	 *
31
	 * @var IConfig
32
	 */
33
	private $config;
34
	
35
	/**
36
	 *
37
	 * @var OcrJobMapper
38
	 */
39
	private $mapper;
40
	
41
	/**
42
	 *
43
	 * @var ILogger
44
	 */
45
	private $logger;
46
	
47
	/**
48
	 *
49
	 * @var IL10N
50
	 */
51
	private $l10n;
52
	
53
	/**
54
	 * 
55
	 * @var string
56
	 */
57
	private $redisHost;
58
	
59
	/**
60
	 * 
61
	 * @var integer
62
	 */
63
	private $redisPort;
64
	
65
	/**
66
	 * 
67
	 * @var integer
68
	 */
69
	private $redisDb;
70
	
71
	/**
72
	 * 
73
	 * @var string
74
	 */
75
	private $appName = 'ocr';
76
	
77
	/**
78
	 * QueueService constructor.
79
	 *
80
	 * @param OcrJobMapper $mapper        	
81
	 * @param IConfig $config        	
82
	 * @param IL10N $l10n        	
83
	 * @param ILogger $logger        	
84
	 */
85
	public function __construct(OcrJobMapper $mapper, IConfig $config, IL10N $l10n, ILogger $logger) {
86
		$this->mapper = $mapper;
87
		$this->logger = $logger;
88
		$this->l10n = $l10n;
89
		$this->config = $config;
90
		$this->redisHost = $this->config->getAppValue ( $this->appName, 'redisHost' );
91
		$this->redisPort = intval($this->config->getAppValue ( $this->appName, 'redisPort' ));
92
		$this->redisDb = intval($this->config->getAppValue ( $this->appName, 'redisDb' ));
93
	}
94
	
95
	/**
96
	 * Inits the client and sends the task to the background worker (async)
97
	 *
98
	 * @param OcrJob $job        	
99
	 * @param string[] $languages        	
100
	 * @param string $occDir        	
101
	 */
102
	public function sendJob($job, $languages, $occDir) {
0 ignored issues
show
Unused Code introduced by
The parameter $occDir is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
103
		try {
104
			// check for messaging and put everything together
105
			$redis = $this->setupRedisInstance ();
106
			
107
			$job = $this->mapper->insert ( $job );
108
			$msg = json_encode ( array (
109
					'id' => $job->getId (),
110
					'type' => $job->getType (),
111
					'source' => $job->getSource (),
112
					'tempFile' => $job->getTempFile (),
113
					'languages' => $languages 
114
			) );
115
			if (! $redis->lPush ( OcrConstants::REDIS_NEW_JOBS_QUEUE, $msg )) {
116
				throw new NotFoundException ( $this->l10n->t ( 'Could not add files to the redis OCR processing queue.' ) );
117
			}
118
		} catch ( Exception $e ) {
119
			exec ( 'rm ' . $job->getTempFile () );
120
			$job->setStatus ( 'FAILED' );
121
			$job->setErrorLog($this->l10n->t ( 'Could not add files to the redis OCR processing queue.' ));
122
			$this->mapper->update ( $job );
123
			$this->handleException ( $e );
124
		}
125
	}
126
	
127
	/**
128
	 * Retrieves all finished jobs from redis and returns them.
129
	 * 
130
	 * @return string[]
131
	 */
132
	public function readingFinishedJobs() {
133
		try {
134
			$redis = $this->setupRedisInstance ();
135
			
136
			$result = $redis->multi ()->lRange ( OcrConstants::REDIS_FINISHED_JOBS_QUEUE, 0, - 1 )->delete ( OcrConstants::REDIS_FINISHED_JOBS_QUEUE )->exec ();
137
			$this->logger->debug ( 'Retrieved the following array from redis: {result}', ['result' => $result[0]]);
138
			return $result[0];
139
		} catch ( Exception $e ) {
140
			$this->handleException ( $e );
141
		}
142
	}
143
	
144
	/**
145
	 * Setup the Redis instance and return to whom ever it needs.
146
	 *
147
	 * @throws NotFoundException
148
	 * @return \Redis
149
	 */
150
	private function setupRedisInstance() {
151 View Code Duplication
		if (! extension_loaded ( 'redis' )) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
152
			$this->logger->debug ( 'It seems that the message queueing capabilities are not available in your local php installation. Please install php-redis.');
153
			throw new NotFoundException ( $this->l10n->t ( 'Message queueing capabilities are missing on the server.' ) );
154
		}
155
		
156
		$redis = new \Redis ();
157
		if (! $redis->connect ( $this->redisHost, $this->redisPort, 2.5, NULL, 100 )) {
158
			$this->logger->debug ( 'Cannot connect to Redis.');
159
			throw new NotFoundException ( $this->l10n->t ( 'Cannot connect to Redis.' ) );
160
		}
161 View Code Duplication
		if (! $redis->select ( $this->redisDb )) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
162
			$this->logger->debug ( 'Cannot connect to the right Redis database.');
163
			throw new NotFoundException ( $this->l10n->t ( 'Cannot connect to the right Redis database.' ) );
164
		}
165
		$redis->setOption ( \Redis::OPT_PREFIX, OcrConstants::REDIS_KEY_PREFIX );
166
		
167
		return $redis;
168
	}
169
	
170
	/**
171
	 * Handle the possible thrown Exceptions from all methods of this class.
172
	 *
173
	 * @param Exception $e        	
174
	 * @throws Exception
175
	 * @throws NotFoundException
176
	 */
177 View Code Duplication
	private function handleException($e) {
178
		$this->logger->logException ( $e, [ 
179
				'app' => 'ocr',
180
				'message' => 'Exception during message queue processing' 
181
		] );
182
		if ($e instanceof NotFoundException) {
183
			throw new NotFoundException ( $e->getMessage () );
184
		} else {
185
			throw $e;
186
		}
187
	}
188
}