Completed
Push — master ( 5d9cd9...874e6e )
by mw
62:18 queued 26:13
created

DeferredCallableUpdate::log()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
cc 2
eloc 4
nc 2
nop 2
dl 0
loc 8
ccs 0
cts 0
cp 0
crap 6
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
namespace SMW;
4
5
use Closure;
6
use DeferrableUpdate;
7
use DeferredUpdates;
8
use RuntimeException;
9
use Psr\Log\LoggerInterface;
10
use Psr\Log\LoggerAwareInterface;
11
12
/**
13
 * @see MWCallableUpdate
14
 *
15
 * @license GNU GPL v2+
16
 * @since 2.4
17
 */
18
class DeferredCallableUpdate implements DeferrableUpdate, LoggerAwareInterface {
19
20
	/**
21
	 * @var Closure|callable
22
	 */
23
	private $callback;
24
25
	/**
26
	 * @var boolean
27
	 */
28
	private $enabledDeferredUpdate = true;
29
30
	/**
31
	 * @var boolean
32
	 */
33
	private $isPending = false;
34
35
	/**
36
	 * @var string
37
	 */
38
	private $origin = '';
39
40
	/**
41
	 * @var array
42
	 */
43
	private static $pendingUpdates = array();
44
45
	/**
46
	 * @var string|null
47
	 */
48
	private $fingerprint = null;
49
50
	/**
51
	 * @var array
52
	 */
53
	private static $queueList = array();
54
55
	/**
56
	 * LoggerInterface
57
	 */
58
	private $logger;
59 273
60
	/**
61 273
	 * @since 2.4
62
	 *
63
	 * @param Closure $callback
64
	 * @throws RuntimeException
65 273
	 */
66 273
	public function __construct( Closure $callback ) {
67
68
		if ( !is_callable( $callback ) ) {
69
			throw new RuntimeException( 'Expected a valid callback/closure!' );
70
		}
71
72
		$this->callback = $callback;
73
	}
74
75 268
	/**
76 268
	 * @see LoggerAwareInterface::setLogger
77 268
	 *
78
	 * @since 2.5
79
	 *
80
	 * @param LoggerInterface $logger
81
	 */
82
	public function setLogger( LoggerInterface $logger ) {
83
		$this->logger = $logger;
84
	}
85
86
	/**
87
	 * @note Unit/Integration tests in MW 1.26- showed ambiguous behaviour when
88
	 * run in deferred mode because not all MW operations were supporting late
89 81
	 * execution.
90 81
	 *
91 81
	 * @since 2.4
92
	 */
93
	public function enabledDeferredUpdate( $enabledDeferredUpdate = true ) {
94
		$this->enabledDeferredUpdate = (bool)$enabledDeferredUpdate;
95
	}
96
97
	/**
98
	 * @note If wgCommandLineMode = true (e.g. MW is in CLI mode) then
99
	 * DeferredUpdates::addUpdate pushes updates directly into execution mode
100
	 * which may not be desirable for all update processes therefore hold on to it
101 5
	 * by using an internal waitableUpdate list and release them at convenience.
102 5
	 *
103 5
	 * @since 2.4
104
	 *
105
	 * @param booloan $isPending
106
	 */
107
	public function markAsPending( $isPending = false ) {
108
		$this->isPending = (bool)$isPending;
109
	}
110 268
111 268
	/**
112 268
	 * @note Set a fingerprint allowing it to track and detect duplicate update
113
	 * requests while being unprocessed.
114
	 *
115
	 * @since 2.5
116
	 *
117
	 * @param string|null $queue
0 ignored issues
show
Bug introduced by
There is no parameter named $queue. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
118
	 */
119
	public function setFingerprint( $fingerprint = null ) {
120
		$this->fingerprint = md5( $fingerprint );
121 1
	}
122 1
123
	/**
124
	 * @since 2.5
125
	 *
126
	 * @param string $origin
127
	 */
128 301
	public function setOrigin( $origin ) {
129 301
		$this->origin = $origin;
130 79
	}
131
132
	/**
133 301
	 * @see DeferrableCallback::getOrigin
134 301
	 *
135
	 * @since 2.5
136
	 *
137
	 * @return string
138
	 */
139
	public function getOrigin() {
140
		return $this->origin;
141 271
	}
142 271
143 271
	/**
144 271
	 * @since 2.4
145 271
	 */
146
	public static function releasePendingUpdates() {
147
		foreach ( self::$pendingUpdates as $update ) {
148
			DeferredUpdates::addUpdate( $update );
149
		}
150
151
		self::$pendingUpdates = array();
152
	}
153
154
	/**
155
	 * @see DeferrableUpdate::doUpdate
156
	 *
157
	 * @since 2.4
158 271
	 */
159
	public function doUpdate() {
160 271
		$this->log( $this->origin . ' doUpdate' . ( $this->fingerprint ? ' (' . $this->fingerprint . ')' : '' ) );
161 1
		call_user_func( $this->callback );
162 1
		unset( self::$queueList[$this->fingerprint] );
163
	}
164
165 271
	/**
166
	 * @since 2.5
167 271
	 */
168 79
	public function pushUpdate() {
169 79
170
		if ( $this->fingerprint !== null && isset( self::$queueList[$this->fingerprint] ) ) {
171
			$this->log( $this->origin . ' (fingerprint: ' . $this->fingerprint .' is already listed therefore skip)' );
172 269
			return;
173 212
		}
174 212
175
		self::$queueList[$this->fingerprint] = true;
176
177 268
		if ( $this->isPending && $this->enabledDeferredUpdate ) {
178 268
			$this->log( $this->origin . ' (as pending DeferredCallableUpdate)' );
179
			return self::$pendingUpdates[] = $this;
180
		}
181
182
		if ( $this->enabledDeferredUpdate ) {
183
			$this->log( $this->origin . ' (as DeferredCallableUpdate)' );
184
			return DeferredUpdates::addUpdate( $this );
185
		}
186
187
		$this->doUpdate();
188
	}
189
190
	private function log( $message, $context = array() ) {
191
192
		if ( $this->logger === null ) {
193
			return;
194
		}
195
196
		$this->logger->info( $message, $context );
197
	}
198
199
}
200