Passed
Push — master ( fdca42...7dd147 )
by Hennik
03:23 queued 10s
created

Resque_Job_Status::fetch()   A

Complexity

Conditions 5
Paths 5

Size

Total Lines 18
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 5.675

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 5
eloc 12
c 1
b 0
f 0
nc 5
nop 1
dl 0
loc 18
ccs 7
cts 10
cp 0.7
crap 5.675
rs 9.5555
1
<?php
2
/**
3
 * Status tracker/information for a job.
4
 *
5
 * @package		Resque/Job
6
 * @author		Chris Boulton <[email protected]>
7
 * @license		http://www.opensource.org/licenses/mit-license.php
8
 */
9
class Resque_Job_Status
10
{
11
	const STATUS_WAITING = 1;
12
	const STATUS_RUNNING = 2;
13
	const STATUS_FAILED = 3;
14
	const STATUS_COMPLETE = 4;
15
16
	/**
17
 	 * @var string The prefix of the job status id.
18
 	 */
19
 	private $prefix;
20
21
	/**
22
	 * @var string The ID of the job this status class refers back to.
23
	 */
24
	private $id;
25
26
	/**
27
	 * @var mixed Cache variable if the status of this job is being monitored or not.
28
	 * 	True/false when checked at least once or null if not checked yet.
29
	 */
30
	private $isTracking = null;
31
32
	/**
33
	 * @var array Array of statuses that are considered final/complete.
34
	 */
35
	private static $completeStatuses = array(
36
		self::STATUS_FAILED,
37
		self::STATUS_COMPLETE
38
	);
39
40
	/**
41
	 * Setup a new instance of the job monitor class for the supplied job ID.
42
	 *
43
	 * @param string $id The ID of the job to manage the status for.
44
	 */
45 19
	public function __construct($id, $prefix = '')
46
	{
47 19
		$this->id = $id;
48 19
		$this->prefix = empty($prefix) ? '' : "${prefix}_";
49
	}
50
51
	/**
52
	 * Create a new status monitor item for the supplied job ID. Will create
53
	 * all necessary keys in Redis to monitor the status of a job.
54
	 *
55
	 * @param string $id The ID of the job to monitor the status of.
56
	 */
57
	public static function create($id, $prefix = "")
58
	{
59 11
		$status = new self($id, $prefix);
60
		$statusPacket = array(
61 11
			'status'  => self::STATUS_WAITING,
62 11
			'updated' => time(),
63 11
			'started' => time(),
64
			'result'  => null,
65
		);
66 11
		Resque::redis()->set((string) $status, json_encode($statusPacket));
0 ignored issues
show
Bug introduced by
The method set() does not exist on Resque_Redis. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

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

66
		Resque::redis()->/** @scrutinizer ignore-call */ set((string) $status, json_encode($statusPacket));
Loading history...
67
68 11
		return $status;
69
	}
70
71
	/**
72
	 * Check if we're actually checking the status of the loaded job status
73
	 * instance.
74
	 *
75
	 * @return boolean True if the status is being monitored, false if not.
76
	 */
77
	public function isTracking()
78
	{
79 18
		if($this->isTracking === false) {
80
			return false;
81
		}
82
83 18
		if(!Resque::redis()->exists((string)$this)) {
0 ignored issues
show
Bug introduced by
The method exists() does not exist on Resque_Redis. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

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

83
		if(!Resque::redis()->/** @scrutinizer ignore-call */ exists((string)$this)) {
Loading history...
84 9
			$this->isTracking = false;
85 9
			return false;
86
		}
87
88 10
		$this->isTracking = true;
89 10
		return true;
90
	}
91
92
	/**
93
	 * Update the status indicator for the current job with a new status.
94
	 *
95
	 * @param int The status of the job (see constants in Resque_Job_Status)
0 ignored issues
show
Bug introduced by
The type The was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
96
	 */
97
	public function update($status, $result = null)
98
	{
99 12
		$status = (int) $status;
100
101 12
		if(!$this->isTracking()) {
102 6
			return;
103
		}
104
105 6
		if($status < self::STATUS_WAITING || $status > self::STATUS_COMPLETE) {
106
			return;
107
		}
108
109
		$statusPacket = array(
110 6
			'status'  => $status,
111 6
			'updated' => time(),
112 6
			'started' => $this->fetch('started'),
113 6
			'result'  => $result,
114
		);
115 6
		Resque::redis()->set((string)$this, json_encode($statusPacket));
116
117
		// Expire the status for completed jobs after 24 hours
118 6
		if(in_array($status, self::$completeStatuses)) {
119 1
			Resque::redis()->expire((string)$this, 86400);
0 ignored issues
show
Bug introduced by
The method expire() does not exist on Resque_Redis. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

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

119
			Resque::redis()->/** @scrutinizer ignore-call */ expire((string)$this, 86400);
Loading history...
120
		}
121 6
	}
122
123
	/**
124
	 * Fetch the status for the job being monitored.
125
	 *
126
	 * @return mixed False if the status is not being monitored, otherwise the status
127
	 * 	as an integer, based on the Resque_Job_Status constants.
128
	 */
129
	public function get()
130
	{
131 14
		return $this->status();
132
	}
133
134
	/**
135
	 * Fetch the status for the job being monitored.
136
	 *
137
	 * @return mixed False if the status is not being monitored, otherwise the status
138
	 * 	as an integer, based on the Resque_Job_Status constants.
139
	 */
140
	public function status()
141
	{
142 14
		return $this->fetch('status');
143
	}
144
145
	/**
146
 	 * Fetch the last update timestamp of the job being monitored.
147
 	 *
148
 	 * @return mixed False if the job is not being monitored, otherwise the
149
	 *  update timestamp.
150
 	 */
151
	public function updated()
152
	{
153
		return $this->fetch('updated');
154
 	}
155
156
	/**
157
 	 * Fetch the start timestamp of the job being monitored.
158
 	 *
159
 	 * @return mixed False if the job is not being monitored, otherwise the
160
	 *  start timestamp.
161
 	 */
162
	public function started()
163
	{
164
		return $this->fetch('started');
165
 	}
166
167
	/**
168
 	 * Fetch the result of the job being monitored.
169
 	 *
170
 	 * @return mixed False if the job is not being monitored, otherwise the result
171
 	 * 	as mixed
172
 	 */
173
	public function result()
174
	{
175
		return $this->fetch('result');
176
 	}
177
178
	/**
179
	 * Stop tracking the status of a job.
180
	 */
181
	public function stop()
182
	{
183 1
		Resque::redis()->del((string)$this);
0 ignored issues
show
Bug introduced by
The method del() does not exist on Resque_Redis. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

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

183
		Resque::redis()->/** @scrutinizer ignore-call */ del((string)$this);
Loading history...
184 1
	}
185
186
	/**
187
	 * Generate a string representation of this object.
188
	 *
189
	 * @return string String representation of the current job status class.
190
	 */
191
	public function __toString()
192
	{
193 19
		return 'job:' . $this->prefix . $this->id . ':status';
194
	}
195
196
	/**
197
	* Fetch a value from the status packet for the job being monitored.
198
	*
199
	* @return mixed False if the status is not being monitored, otherwise the
200
	*  requested value from the status packet.
201
	*/
202
	protected function fetch($value = null)
203
	{
204 14
		if(!$this->isTracking()) {
205 6
			return false;
206
		}
207
208 9
		$statusPacket = json_decode(Resque::redis()->get((string)$this), true);
0 ignored issues
show
Bug introduced by
The method get() does not exist on Resque_Redis. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

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

208
		$statusPacket = json_decode(Resque::redis()->/** @scrutinizer ignore-call */ get((string)$this), true);
Loading history...
209 9
		if(!$statusPacket) {
210
			return false;
211
		}
212
213 9
		if(empty($value)) {
214
			return $statusPacket;
215
		} else {
216 9
			if(isset($statusPacket[$value])) {
217 9
				return $statusPacket[$value];
218
			} else {
219
				return null;
220
			}
221
		}
222
223
	}
224
}
225