PluginProbe ʕ •ᴥ•ʔ
Matomo Analytics – Powerful, Privacy-First Insights for WordPress / 4.14.1
Matomo Analytics – Powerful, Privacy-First Insights for WordPress v4.14.1
5.12.0 5.11.1 5.11.0 5.10.2 5.10.1 trunk 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.1.0 1.1.1 1.1.2 1.1.3 1.2.0 1.3.0 1.3.1 1.3.2 4.0.0 4.0.1 4.0.2 4.0.3 4.0.4 4.1.0 4.1.1 4.1.2 4.1.3 4.10.0 4.11.0 4.12.0 4.13.0 4.13.2 4.13.3 4.13.4 4.13.5 4.14.0 4.14.1 4.14.2 4.15.0 4.15.1 4.15.2 4.15.3 4.2.0 4.3.0 4.3.1 4.4.1 4.4.2 4.5.0 4.6.0 5.0.1 5.0.2 5.0.3 5.0.4 5.0.5 5.0.6 5.0.7 5.0.8 5.1.0 5.1.1 5.1.2 5.1.3 5.1.4 5.1.5 5.1.6 5.1.7 5.10.0 5.2.0 5.2.1 5.2.2 5.3.0 5.3.1 5.3.2 5.3.3 5.6.0 5.6.1 5.7.0 5.7.1 5.8.0 5.8.1 5.8.2
matomo / app / core / Scheduler / Timetable.php
matomo / app / core / Scheduler Last commit date
Schedule 4 years ago RetryableException.php 4 years ago Scheduler.php 4 years ago Task.php 5 years ago TaskLoader.php 5 years ago Timetable.php 4 years ago
Timetable.php
241 lines
1 <?php
2 /**
3 * Matomo - free/libre analytics platform
4 *
5 * @link https://matomo.org
6 * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
7 *
8 */
9
10 namespace Piwik\Scheduler;
11
12 use Piwik\Common;
13 use Piwik\Option;
14 use Piwik\Date;
15
16 /**
17 * This data structure holds the scheduled times for each active scheduled task.
18 */
19 class Timetable
20 {
21 const TIMETABLE_OPTION_STRING = "TaskScheduler.timetable";
22 const RETRY_OPTION_STRING = "TaskScheduler.retryList";
23
24 private $timetable;
25 private $retryList;
26
27 public function __construct()
28 {
29 $this->readFromOption();
30 }
31
32 public function getTimetable()
33 {
34 return $this->timetable;
35 }
36
37 public function setTimetable($timetable)
38 {
39 $this->timetable = $timetable;
40 }
41
42 public function setRetryList($retryList)
43 {
44 $this->retryList = $retryList;
45 }
46
47 /**
48 * @param Task[] $activeTasks
49 */
50 public function removeInactiveTasks($activeTasks)
51 {
52 $activeTaskNames = array();
53 foreach ($activeTasks as $task) {
54 $activeTaskNames[] = $task->getName();
55 }
56 foreach (array_keys($this->timetable) as $taskName) {
57 if (!in_array($taskName, $activeTaskNames)) {
58 unset($this->timetable[$taskName]);
59 }
60 }
61 $this->save();
62 }
63
64 public function getScheduledTaskNames()
65 {
66 return array_keys($this->timetable);
67 }
68
69 public function getScheduledTaskTime($taskName)
70 {
71 return isset($this->timetable[$taskName]) ? Date::factory($this->timetable[$taskName]) : false;
72 }
73
74 /**
75 * Checks if the task should be executed
76 *
77 * Task has to be executed if :
78 * - the task has already been scheduled once and the current system time is greater than the scheduled time.
79 * - execution is forced, see $forceTaskExecution
80 *
81 * @param string $taskName
82 *
83 * @return boolean
84 */
85 public function shouldExecuteTask($taskName)
86 {
87 $forceTaskExecution = (defined('DEBUG_FORCE_SCHEDULED_TASKS') && DEBUG_FORCE_SCHEDULED_TASKS);
88
89 if ($forceTaskExecution) {
90 return true;
91 }
92
93 return $this->taskHasBeenScheduledOnce($taskName) && time() >= $this->timetable[$taskName];
94 }
95
96 /**
97 * Checks if a task should be rescheduled
98 *
99 * Task has to be rescheduled if :
100 * - the task has to be executed
101 * - the task has never been scheduled before
102 *
103 * @param string $taskName
104 *
105 * @return boolean
106 */
107 public function taskShouldBeRescheduled($taskName)
108 {
109 return !$this->taskHasBeenScheduledOnce($taskName) || $this->shouldExecuteTask($taskName);
110 }
111
112 public function rescheduleTask(Task $task)
113 {
114 $rescheduledTime = $task->getRescheduledTime();
115
116 // update the scheduled time
117 $this->timetable[$task->getName()] = $rescheduledTime;
118 $this->save();
119
120 return Date::factory($rescheduledTime);
121 }
122
123 public function rescheduleTaskAndRunTomorrow(Task $task)
124 {
125 $tomorrow = Date::factory('tomorrow');
126
127 // update the scheduled time
128 $this->timetable[$task->getName()] = $tomorrow->getTimestamp();
129 $this->save();
130
131 return $tomorrow;
132 }
133
134 public function rescheduleTaskAndRunInOneHour(Task $task)
135 {
136 $oneHourFromNow = Date::factory('now')->addHour(1);
137
138 // update the scheduled time
139 $this->timetable[$task->getName()] = $oneHourFromNow->getTimestamp();
140 $this->save();
141
142 return $oneHourFromNow;
143 }
144
145 public function save()
146 {
147 Option::set(self::TIMETABLE_OPTION_STRING, serialize($this->timetable));
148 }
149
150 public function getScheduledTimeForMethod($className, $methodName, $methodParameter = null)
151 {
152 $taskName = Task::getTaskName($className, $methodName, $methodParameter);
153
154 return $this->taskHasBeenScheduledOnce($taskName) ? $this->timetable[$taskName] : false;
155 }
156
157 public function taskHasBeenScheduledOnce($taskName)
158 {
159 return isset($this->timetable[$taskName]);
160 }
161
162 public function readFromOption()
163 {
164 Option::clearCachedOption(self::TIMETABLE_OPTION_STRING);
165 $optionData = Option::get(self::TIMETABLE_OPTION_STRING);
166 $unserializedTimetable = Common::safe_unserialize($optionData);
167
168 $this->timetable = $unserializedTimetable === false ? array() : $unserializedTimetable;
169 }
170
171 /**
172 * Read the retry list option from the database
173 *
174 * @throws \Throwable
175 */
176 private function readRetryList()
177 {
178 Option::clearCachedOption(self::RETRY_OPTION_STRING);
179 $retryData = Option::get(self::RETRY_OPTION_STRING);
180 $unserializedRetryList = Common::safe_unserialize($retryData);
181
182 $this->retryList = $unserializedRetryList === false ? array() : $unserializedRetryList;
183 }
184
185 /**
186 * Save the retry list option to the database
187 */
188 public function saveRetryList()
189 {
190 Option::set(self::RETRY_OPTION_STRING, serialize($this->retryList));
191 }
192
193 /**
194 * Remove a task from the retry list
195 *
196 * @param string $taskName
197 */
198 public function clearRetryCount(string $taskName)
199 {
200 if (isset($this->retryList[$taskName])) {
201 unset($this->retryList[$taskName]);
202 $this->saveRetryList();
203 }
204 }
205
206 /**
207 * Increment the retry counter for a task
208 *
209 * @param string $taskName
210 */
211 public function incrementRetryCount(string $taskName)
212 {
213 $this->readRetryList();
214 if (!isset($this->retryList[$taskName])) {
215 $this->retryList[$taskName] = 0;
216 }
217 $this->retryList[$taskName]++;
218 $this->saveRetryList();
219 }
220
221 /**
222 * Return the current number of retries for a task
223 *
224 * @param string $taskName
225 *
226 * @return int
227 */
228 public function getRetryCount(string $taskName) : int
229 {
230 $this->readRetryList();
231
232 // Ignore excessive retry counts, workaround for SchedulerTest mock
233 if (!isset($this->retryList[$taskName]) || $this->retryList[$taskName] > 10000) {
234 return 0;
235 }
236
237 return $this->retryList[$taskName];
238 }
239
240 }
241