Test Failed
Pull Request — main (#56)
by
unknown
03:57
created

JobHandler::getPrefix()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 3
nc 2
nop 0
dl 0
loc 7
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Resque;
4
5
use InvalidArgumentException;
6
use Resque\Job\Status;
7
use Resque\Exceptions\DoNotPerformException;
8
use Resque\Job\FactoryInterface;
9
use Resque\Job\Factory;
10
use Error;
11
12
/**
13
 * Resque job.
14
 *
15
 * @package		Resque/JobHandler
16
 * @author		Chris Boulton <[email protected]>
17
 * @license		http://www.opensource.org/licenses/mit-license.php
18
 */
19
class JobHandler
20
{
21
	/**
22
	 * @var string The name of the queue that this job belongs to.
23
	 */
24
	public $queue;
25
26
	/**
27
	 * @var \Resque\Worker\Resque Instance of the Resque worker running this job.
28
	 */
29
	public $worker;
30
31
	/**
32
	 * @var array Array containing details of the job.
33
	 */
34
	public $payload;
35
36
	/**
37
	 * @var object|\Resque\Job\JobInterface Instance of the class performing work for this job.
38
	 */
39
	private $instance;
40
41
	/**
42
	 * @var \Resque\Job\FactoryInterface
43
	 */
44
	private $jobFactory;
45
46
	/**
47
	 * Instantiate a new instance of a job.
48
	 *
49
	 * @param string $queue The queue that the job belongs to.
50
	 * @param array $payload array containing details of the job.
51
	 */
52
	public function __construct($queue, $payload)
53
	{
54
		$this->queue = $queue;
55
		$this->payload = $payload;
56
	}
57
58
	/**
59
	 * Create a new job and save it to the specified queue.
60
	 *
61
	 * @param string $queue The name of the queue to place the job in.
62
	 * @param string $class The name of the class that contains the code to execute the job.
63
	 * @param array $args Any optional arguments that should be passed when the job is executed.
64
	 * @param boolean $monitor Set to true to be able to monitor the status of a job.
65
	 * @param string $id Unique identifier for tracking the job. Generated if not supplied.
66
	 * @param string $prefix The prefix needs to be set for the status key
67
	 *
68
	 * @return string
69
	 * @throws \InvalidArgumentException
70
	 */
71
	public static function create($queue, $class, $args = null, $monitor = false, $id = null, $prefix = "")
72
	{
73
		if (is_null($id)) {
74
			$id = Resque::generateJobId();
75
		}
76
77
		if ($args !== null && !is_array($args)) {
0 ignored issues
show
introduced by
The condition is_array($args) is always true.
Loading history...
78
			throw new InvalidArgumentException(
79
				'Supplied $args must be an array.'
80
			);
81
		}
82
		Resque::push($queue, array(
83
			'class'	     => $class,
84
			'args'	     => array($args),
85
			'id'	     => $id,
86
			'prefix'     => $prefix,
87
			'queue_time' => microtime(true),
88
		));
89
90
		if ($monitor) {
91
			Status::create($id, $prefix);
92
		}
93
94
		return $id;
95
	}
96
97
	/**
98
	 * Find the next available job from the specified queue and return an
99
	 * instance of JobHandler for it.
100
	 *
101
	 * @param string $queue The name of the queue to check for a job in.
102
	 * @return false|object Null when there aren't any waiting jobs, instance of Resque\JobHandler when a job was found.
103
	 */
104
	public static function reserve($queue)
105
	{
106
		$payload = Resque::pop($queue);
107
		if (!is_array($payload)) {
0 ignored issues
show
introduced by
The condition is_array($payload) is always true.
Loading history...
108
			return false;
109
		}
110
111
		return new JobHandler($queue, $payload);
112
	}
113
114
	/**
115
	 * Find the next available job from the specified queues using blocking list pop
116
	 * and return an instance of JobHandler for it.
117
	 *
118
	 * @param array             $queues
119
	 * @param int               $timeout
120
	 * @return false|object Null when there aren't any waiting jobs, instance of Resque\JobHandler when a job was found.
121
	 */
122
	public static function reserveBlocking(array $queues, $timeout = null)
123
	{
124
		$item = Resque::blpop($queues, $timeout);
125
126
		if (!is_array($item)) {
127
			return false;
128
		}
129
130
		return new JobHandler($item['queue'], $item['payload']);
131
	}
132
133
	/**
134
	 * Update the status of the current job.
135
	 *
136
	 * @param int $status Status constant from Resque\Job\Status indicating the current status of a job.
137
	 */
138
	public function updateStatus($status, $result = null)
139
	{
140
		if (empty($this->payload['id'])) {
141
			return;
142
		}
143
144
		$statusInstance = new Status($this->payload['id'], $this->getPrefix());
145
		$statusInstance->update($status, $result);
146
	}
147
148
	/**
149
	 * Return the status of the current job.
150
	 *
151
	 * @return int|null The status of the job as one of the Resque\Job\Status constants or null if job is not being tracked.
152
	 */
153
	public function getStatus()
154
	{
155
		if (empty($this->payload['id'])) {
156
			return null;
157
		}
158
159
		$status = new Status($this->payload['id'], $this->getPrefix());
160
		return $status->get();
0 ignored issues
show
Bug Best Practice introduced by
The expression return $status->get() could also return false which is incompatible with the documented return type integer|null. Did you maybe forget to handle an error condition?

If the returned type also contains false, it is an indicator that maybe an error condition leading to the specific return statement remains unhandled.

Loading history...
161
	}
162
163
	/**
164
	 * Get the arguments supplied to this job.
165
	 *
166
	 * @return array Array of arguments.
167
	 */
168
	public function getArguments()
169
	{
170
		if (!isset($this->payload['args'])) {
171
			return array();
172
		}
173
174
		return $this->payload['args'][0];
175
	}
176
177
	/**
178
	 * Get the instantiated object for this job that will be performing work.
179
	 * @return \Resque\Job\JobInterface Instance of the object that this job belongs to.
180
	 * @throws \Resque\Exceptions\ResqueException
181
	 */
182
	public function getInstance()
183
	{
184
		if (!is_null($this->instance)) {
185
			return $this->instance;
186
		}
187
188
		$this->instance = $this->getJobFactory()->create($this->payload['class'], $this->getArguments(), $this->queue);
189
		$this->instance->job = $this;
190
		return $this->instance;
191
	}
192
193
	/**
194
	 * Actually execute a job by calling the perform method on the class
195
	 * associated with the job with the supplied arguments.
196
	 *
197
	 * @return bool
198
	 * @throws Resque\Exceptions\ResqueException When the job's class could not be found or it does not contain a perform method.
199
	 */
200
	public function perform()
201
	{
202
		$result = true;
203
		try {
204
			Event::trigger('beforePerform', $this);
205
206
			$instance = $this->getInstance();
207
			if (is_callable([$instance, 'setUp'])) {
208
				$instance->setUp();
0 ignored issues
show
Bug introduced by
The method setUp() does not exist on Resque\Job\JobInterface. ( Ignorable by Annotation )

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

208
				$instance->/** @scrutinizer ignore-call */ 
209
               setUp();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
209
			}
210
211
			$result = $instance->perform();
212
213
			if (is_callable([$instance, 'tearDown'])) {
214
				$instance->tearDown();
0 ignored issues
show
Bug introduced by
The method tearDown() does not exist on Resque\Job\JobInterface. ( Ignorable by Annotation )

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

214
				$instance->/** @scrutinizer ignore-call */ 
215
               tearDown();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
215
			}
216
217
			Event::trigger('afterPerform', $this);
218
		} catch (DoNotPerformException $e) {
219
			// beforePerform/setUp have said don't perform this job. Return.
220
			$result = false;
221
		}
222
223
		return $result;
224
	}
225
226
	/**
227
	 * Mark the current job as having failed.
228
	 *
229
	 * @param $exception
230
	 */
231
	public function fail($exception)
232
	{
233
		Event::trigger('onFailure', array(
234
			'exception' => $exception,
235
			'job' => $this,
236
		));
237
238
		$this->updateStatus(Status::STATUS_FAILED);
239
		if ($exception instanceof Error) {
240
			FailureHandler::createFromError(
241
				$this->payload,
242
				$exception,
243
				$this->worker,
244
				$this->queue
245
			);
246
		} else {
247
			FailureHandler::create(
248
				$this->payload,
249
				$exception,
250
				$this->worker,
251
				$this->queue
252
			);
253
		}
254
		Stat::incr('failed');
255
		Stat::incr('failed:' . $this->worker);
256
	}
257
258
	/**
259
	 * Re-queue the current job.
260
	 * @return string
261
	 */
262
	public function recreate()
263
	{
264
		$monitor = false;
265
		if (!empty($this->payload['id'])) {
266
			$status = new Status($this->payload['id'], $this->getPrefix());
267
			if ($status->isTracking()) {
268
				$monitor = true;
269
			}
270
		}
271
272
		return self::create($this->queue, $this->payload['class'], $this->getArguments(), $monitor, null, $this->getPrefix());
273
	}
274
275
	/**
276
	 * Generate a string representation used to describe the current job.
277
	 *
278
	 * @return string The string representation of the job.
279
	 */
280
	public function __toString()
281
	{
282
		$name = array(
283
			'Job{' . $this->queue . '}'
284
		);
285
		if (!empty($this->payload['id'])) {
286
			$name[] = 'ID: ' . $this->payload['id'];
287
		}
288
		$name[] = $this->payload['class'];
289
		if (!empty($this->payload['args'])) {
290
			$name[] = json_encode($this->payload['args']);
291
		}
292
		return '(' . implode(' | ', $name) . ')';
293
	}
294
295
	/**
296
	 * @param Resque\Job\FactoryInterface $jobFactory
0 ignored issues
show
Bug introduced by
The type Resque\Resque\Job\FactoryInterface was not found. Did you mean Resque\Job\FactoryInterface? If so, make sure to prefix the type with \.
Loading history...
297
	 * @return Resque\JobHandler
0 ignored issues
show
Bug introduced by
The type Resque\Resque\JobHandler was not found. Did you mean Resque\JobHandler? If so, make sure to prefix the type with \.
Loading history...
298
	 */
299
	public function setJobFactory(FactoryInterface $jobFactory)
300
	{
301
		$this->jobFactory = $jobFactory;
302
303
		return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type Resque\JobHandler which is incompatible with the documented return type Resque\Resque\JobHandler.
Loading history...
304
	}
305
306
	/**
307
	 * @return Resque\Job\FactoryInterface
308
	 */
309
	public function getJobFactory()
310
	{
311
		if ($this->jobFactory === null) {
312
			$this->jobFactory = new Factory();
313
		}
314
		return $this->jobFactory;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->jobFactory returns the type Resque\Job\Factory|Resque\Job\FactoryInterface which is incompatible with the documented return type Resque\Resque\Job\FactoryInterface.
Loading history...
315
	}
316
317
	/**
318
	 * @return string
319
	 */
320
	private function getPrefix()
321
	{
322
		if (isset($this->payload['prefix'])) {
323
			return $this->payload['prefix'];
324
		}
325
326
		return '';
327
	}
328
}
329