Mercurial > hg > isophonics-drupal-site
comparison core/lib/Drupal/Core/Cron.php @ 0:4c8ae668cc8c
Initial import (non-working)
author | Chris Cannam |
---|---|
date | Wed, 29 Nov 2017 16:09:58 +0000 |
parents | |
children | 1fec387a4317 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:4c8ae668cc8c |
---|---|
1 <?php | |
2 | |
3 namespace Drupal\Core; | |
4 | |
5 use Drupal\Component\Utility\Timer; | |
6 use Drupal\Core\Extension\ModuleHandlerInterface; | |
7 use Drupal\Core\Queue\QueueWorkerManagerInterface; | |
8 use Drupal\Core\Queue\RequeueException; | |
9 use Drupal\Core\State\StateInterface; | |
10 use Drupal\Core\Lock\LockBackendInterface; | |
11 use Drupal\Core\Queue\QueueFactory; | |
12 use Drupal\Core\Session\AnonymousUserSession; | |
13 use Drupal\Core\Session\AccountSwitcherInterface; | |
14 use Drupal\Core\Queue\SuspendQueueException; | |
15 use Psr\Log\LoggerInterface; | |
16 use Psr\Log\NullLogger; | |
17 | |
18 /** | |
19 * The Drupal core Cron service. | |
20 */ | |
21 class Cron implements CronInterface { | |
22 | |
23 /** | |
24 * The module handler service. | |
25 * | |
26 * @var \Drupal\Core\Extension\ModuleHandlerInterface | |
27 */ | |
28 protected $moduleHandler; | |
29 | |
30 /** | |
31 * The lock service. | |
32 * | |
33 * @var \Drupal\Core\Lock\LockBackendInterface | |
34 */ | |
35 protected $lock; | |
36 | |
37 /** | |
38 * The queue service. | |
39 * | |
40 * @var \Drupal\Core\Queue\QueueFactory | |
41 */ | |
42 protected $queueFactory; | |
43 | |
44 /** | |
45 * The state service. | |
46 * | |
47 * @var \Drupal\Core\State\StateInterface | |
48 */ | |
49 protected $state; | |
50 | |
51 /** | |
52 * The account switcher service. | |
53 * | |
54 * @var \Drupal\Core\Session\AccountSwitcherInterface | |
55 */ | |
56 protected $accountSwitcher; | |
57 | |
58 /** | |
59 * A logger instance. | |
60 * | |
61 * @var \Psr\Log\LoggerInterface | |
62 */ | |
63 protected $logger; | |
64 | |
65 /** | |
66 * The queue plugin manager. | |
67 * | |
68 * @var \Drupal\Core\Queue\QueueWorkerManagerInterface | |
69 */ | |
70 protected $queueManager; | |
71 | |
72 /** | |
73 * Constructs a cron object. | |
74 * | |
75 * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler | |
76 * The module handler | |
77 * @param \Drupal\Core\Lock\LockBackendInterface $lock | |
78 * The lock service. | |
79 * @param \Drupal\Core\Queue\QueueFactory $queue_factory | |
80 * The queue service. | |
81 * @param \Drupal\Core\State\StateInterface $state | |
82 * The state service. | |
83 * @param \Drupal\Core\Session\AccountSwitcherInterface $account_switcher | |
84 * The account switching service. | |
85 * @param \Psr\Log\LoggerInterface $logger | |
86 * A logger instance. | |
87 * @param \Drupal\Core\Queue\QueueWorkerManagerInterface $queue_manager | |
88 * The queue plugin manager. | |
89 */ | |
90 public function __construct(ModuleHandlerInterface $module_handler, LockBackendInterface $lock, QueueFactory $queue_factory, StateInterface $state, AccountSwitcherInterface $account_switcher, LoggerInterface $logger, QueueWorkerManagerInterface $queue_manager) { | |
91 $this->moduleHandler = $module_handler; | |
92 $this->lock = $lock; | |
93 $this->queueFactory = $queue_factory; | |
94 $this->state = $state; | |
95 $this->accountSwitcher = $account_switcher; | |
96 $this->logger = $logger; | |
97 $this->queueManager = $queue_manager; | |
98 } | |
99 | |
100 /** | |
101 * {@inheritdoc} | |
102 */ | |
103 public function run() { | |
104 // Allow execution to continue even if the request gets cancelled. | |
105 @ignore_user_abort(TRUE); | |
106 | |
107 // Force the current user to anonymous to ensure consistent permissions on | |
108 // cron runs. | |
109 $this->accountSwitcher->switchTo(new AnonymousUserSession()); | |
110 | |
111 // Try to allocate enough time to run all the hook_cron implementations. | |
112 drupal_set_time_limit(240); | |
113 | |
114 $return = FALSE; | |
115 | |
116 // Try to acquire cron lock. | |
117 if (!$this->lock->acquire('cron', 900.0)) { | |
118 // Cron is still running normally. | |
119 $this->logger->warning('Attempting to re-run cron while it is already running.'); | |
120 } | |
121 else { | |
122 $this->invokeCronHandlers(); | |
123 $this->setCronLastTime(); | |
124 | |
125 // Release cron lock. | |
126 $this->lock->release('cron'); | |
127 | |
128 // Return TRUE so other functions can check if it did run successfully | |
129 $return = TRUE; | |
130 } | |
131 | |
132 // Process cron queues. | |
133 $this->processQueues(); | |
134 | |
135 // Restore the user. | |
136 $this->accountSwitcher->switchBack(); | |
137 | |
138 return $return; | |
139 } | |
140 | |
141 /** | |
142 * Records and logs the request time for this cron invocation. | |
143 */ | |
144 protected function setCronLastTime() { | |
145 // Record cron time. | |
146 $this->state->set('system.cron_last', REQUEST_TIME); | |
147 $this->logger->notice('Cron run completed.'); | |
148 } | |
149 | |
150 /** | |
151 * Processes cron queues. | |
152 */ | |
153 protected function processQueues() { | |
154 // Grab the defined cron queues. | |
155 foreach ($this->queueManager->getDefinitions() as $queue_name => $info) { | |
156 if (isset($info['cron'])) { | |
157 // Make sure every queue exists. There is no harm in trying to recreate | |
158 // an existing queue. | |
159 $this->queueFactory->get($queue_name)->createQueue(); | |
160 | |
161 $queue_worker = $this->queueManager->createInstance($queue_name); | |
162 $end = time() + (isset($info['cron']['time']) ? $info['cron']['time'] : 15); | |
163 $queue = $this->queueFactory->get($queue_name); | |
164 $lease_time = isset($info['cron']['time']) ?: NULL; | |
165 while (time() < $end && ($item = $queue->claimItem($lease_time))) { | |
166 try { | |
167 $queue_worker->processItem($item->data); | |
168 $queue->deleteItem($item); | |
169 } | |
170 catch (RequeueException $e) { | |
171 // The worker requested the task be immediately requeued. | |
172 $queue->releaseItem($item); | |
173 } | |
174 catch (SuspendQueueException $e) { | |
175 // If the worker indicates there is a problem with the whole queue, | |
176 // release the item and skip to the next queue. | |
177 $queue->releaseItem($item); | |
178 | |
179 watchdog_exception('cron', $e); | |
180 | |
181 // Skip to the next queue. | |
182 continue 2; | |
183 } | |
184 catch (\Exception $e) { | |
185 // In case of any other kind of exception, log it and leave the item | |
186 // in the queue to be processed again later. | |
187 watchdog_exception('cron', $e); | |
188 } | |
189 } | |
190 } | |
191 } | |
192 } | |
193 | |
194 /** | |
195 * Invokes any cron handlers implementing hook_cron. | |
196 */ | |
197 protected function invokeCronHandlers() { | |
198 $module_previous = ''; | |
199 | |
200 // If detailed logging isn't enabled, don't log individual execution times. | |
201 $time_logging_enabled = \Drupal::config('system.cron')->get('logging'); | |
202 $logger = $time_logging_enabled ? $this->logger : new NullLogger(); | |
203 | |
204 // Iterate through the modules calling their cron handlers (if any): | |
205 foreach ($this->moduleHandler->getImplementations('cron') as $module) { | |
206 | |
207 if (!$module_previous) { | |
208 $logger->notice('Starting execution of @module_cron().', [ | |
209 '@module' => $module, | |
210 ]); | |
211 } | |
212 else { | |
213 $logger->notice('Starting execution of @module_cron(), execution of @module_previous_cron() took @time.', [ | |
214 '@module' => $module, | |
215 '@module_previous' => $module_previous, | |
216 '@time' => Timer::read('cron_' . $module_previous) . 'ms', | |
217 ]); | |
218 } | |
219 Timer::start('cron_' . $module); | |
220 | |
221 // Do not let an exception thrown by one module disturb another. | |
222 try { | |
223 $this->moduleHandler->invoke($module, 'cron'); | |
224 } | |
225 catch (\Exception $e) { | |
226 watchdog_exception('cron', $e); | |
227 } | |
228 | |
229 Timer::stop('cron_' . $module); | |
230 $module_previous = $module; | |
231 } | |
232 if ($module_previous) { | |
233 $logger->notice('Execution of @module_previous_cron() took @time.', [ | |
234 '@module_previous' => $module_previous, | |
235 '@time' => Timer::read('cron_' . $module_previous) . 'ms', | |
236 ]); | |
237 } | |
238 } | |
239 | |
240 } |