ILIAS  release_9 Revision v9.13-25-g2c18ec4c24f
ilCronManagerImpl Class Reference
+ Inheritance diagram for ilCronManagerImpl:
+ Collaboration diagram for ilCronManagerImpl:

Public Member Functions

 __construct (private readonly ilCronJobRepository $cronRepository, private readonly ilDBInterface $db, private readonly ilSetting $settings, private readonly ilLogger $logger, private readonly ClockFactory $clock_factory)
 
 runActiveJobs (ilObjUser $actor)
 
 runJobManual (string $jobId, ilObjUser $actor)
 
 resetJob (ilCronJob $job, ilObjUser $actor)
 
 activateJob (ilCronJob $job, ilObjUser $actor, bool $wasManuallyExecuted=false)
 
 deactivateJob (ilCronJob $job, ilObjUser $actor, bool $wasManuallyExecuted=false)
 
 isJobActive (string $jobId)
 
 isJobInactive (string $jobId)
 
 ping (string $jobId)
 

Private Member Functions

 getMicrotime ()
 
 runJob (ilCronJob $job, ilObjUser $actor, ?array $jobData=null, bool $isManualExecution=false)
 Run single cron job (internal) More...
 

Detailed Description

Definition at line 24 of file class.ilCronManagerImpl.php.

Constructor & Destructor Documentation

◆ __construct()

ilCronManagerImpl::__construct ( private readonly ilCronJobRepository  $cronRepository,
private readonly ilDBInterface  $db,
private readonly ilSetting  $settings,
private readonly ilLogger  $logger,
private readonly ClockFactory  $clock_factory 
)

Definition at line 26 of file class.ilCronManagerImpl.php.

32  {
33  }

Member Function Documentation

◆ activateJob()

ilCronManagerImpl::activateJob ( ilCronJob  $job,
ilObjUser  $actor,
bool  $wasManuallyExecuted = false 
)

Implements ilCronManager.

Definition at line 229 of file class.ilCronManagerImpl.php.

References ilCronJob\activationWasToggled(), and ILIAS\Repository\settings().

Referenced by resetJob().

229  : void
230  {
231  $this->cronRepository->activateJob($job, $this->clock_factory->system()->now(), $actor, $wasManuallyExecuted);
232  $job->activationWasToggled($this->db, $this->settings, true);
233  }
activationWasToggled(ilDBInterface $db, ilSetting $setting, bool $a_currently_active)
Important: This method is (also) called from the setup process, where the constructor of an ilCronJob...
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ deactivateJob()

ilCronManagerImpl::deactivateJob ( ilCronJob  $job,
ilObjUser  $actor,
bool  $wasManuallyExecuted = false 
)

Implements ilCronManager.

Definition at line 235 of file class.ilCronManagerImpl.php.

References ilCronJob\activationWasToggled(), and ILIAS\Repository\settings().

Referenced by runJob().

235  : void
236  {
237  $this->cronRepository->deactivateJob($job, $this->clock_factory->system()->now(), $actor, $wasManuallyExecuted);
238  $job->activationWasToggled($this->db, $this->settings, false);
239  }
activationWasToggled(ilDBInterface $db, ilSetting $setting, bool $a_currently_active)
Important: This method is (also) called from the setup process, where the constructor of an ilCronJob...
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ getMicrotime()

ilCronManagerImpl::getMicrotime ( )
private

Definition at line 35 of file class.ilCronManagerImpl.php.

Referenced by runJob().

35  : float
36  {
37  return ((int) $this->clock_factory->system()->now()->format('Uu')) / 1000000;
38  }
+ Here is the caller graph for this function:

◆ isJobActive()

ilCronManagerImpl::isJobActive ( string  $jobId)

Implements ilCronManager.

Definition at line 241 of file class.ilCronManagerImpl.php.

241  : bool
242  {
243  $jobs_data = $this->cronRepository->getCronJobData($jobId);
244 
245  return $jobs_data !== [] && $jobs_data[0]['job_status'];
246  }

◆ isJobInactive()

ilCronManagerImpl::isJobInactive ( string  $jobId)

Implements ilCronManager.

Definition at line 248 of file class.ilCronManagerImpl.php.

248  : bool
249  {
250  $jobs_data = $this->cronRepository->getCronJobData($jobId);
251 
252  return $jobs_data !== [] && !((bool) $jobs_data[0]['job_status']);
253  }

◆ ping()

ilCronManagerImpl::ping ( string  $jobId)

Implements ilCronManager.

Definition at line 255 of file class.ilCronManagerImpl.php.

255  : void
256  {
257  $this->db->manipulateF(
258  'UPDATE cron_job SET alive_ts = %s WHERE job_id = %s',
259  ['integer', 'text'],
260  [$this->clock_factory->system()->now()->getTimestamp(), $jobId]
261  );
262  }

◆ resetJob()

ilCronManagerImpl::resetJob ( ilCronJob  $job,
ilObjUser  $actor 
)

Implements ilCronManager.

Definition at line 210 of file class.ilCronManagerImpl.php.

References activateJob(), ilCronJobResult\CODE_MANUAL_RESET, and ilCronJobResult\STATUS_RESET.

210  : void
211  {
212  $result = new ilCronJobResult();
213  $result->setStatus(ilCronJobResult::STATUS_RESET);
214  $result->setCode(ilCronJobResult::CODE_MANUAL_RESET);
215  $result->setMessage('Cron job re-activated by admin');
216 
217  $this->cronRepository->updateJobResult(
218  $job,
219  $this->clock_factory->system()->now(),
220  $actor,
221  $result,
222  true
223  );
224  $this->cronRepository->resetJob($job);
225 
226  $this->activateJob($job, $actor, true);
227  }
final const CODE_MANUAL_RESET
activateJob(ilCronJob $job, ilObjUser $actor, bool $wasManuallyExecuted=false)
+ Here is the call graph for this function:

◆ runActiveJobs()

ilCronManagerImpl::runActiveJobs ( ilObjUser  $actor)

Implements ilCronManager.

Definition at line 40 of file class.ilCronManagerImpl.php.

References ilUtil\_getHttpPath(), ilSetting\_lookupValue(), ilDatePresentation\formatDate(), IL_CAL_UNIX, ILIAS\Repository\logger(), runJob(), ILIAS\Repository\settings(), ilDatePresentation\setUseRelativeDates(), and ilDatePresentation\useRelativeDates().

40  : void
41  {
42  $this->logger->info('CRON - batch start');
43 
44  $ts = $this->clock_factory->system()->now()->getTimestamp();
45  $this->settings->set('last_cronjob_start_ts', (string) $ts);
46 
47  $useRelativeDates = ilDatePresentation::useRelativeDates();
49  $this->logger->info(sprintf(
50  'Set last datetime to: %s',
52  ));
53  $this->logger->info(sprintf(
54  'Verification of last run datetime (read from database): %s',
56  new ilDateTime(ilSetting::_lookupValue('common', 'last_cronjob_start_ts'), IL_CAL_UNIX)
57  )
58  ));
59  ilDatePresentation::setUseRelativeDates($useRelativeDates);
60 
61  // ilLink::_getStaticLink() should work in crons
62  if (!defined('ILIAS_HTTP_PATH')) {
63  define('ILIAS_HTTP_PATH', ilUtil::_getHttpPath());
64  }
65 
66  // system
67  foreach ($this->cronRepository->getCronJobData(null, false) as $row) {
68  $job = $this->cronRepository->getJobInstanceById($row['job_id']);
69  if ($job instanceof ilCronJob) {
70  // #18411 - we are NOT using the initial job data as it might be outdated at this point
71  $this->runJob($job, $actor);
72  }
73  }
74 
75  // plugins
76  foreach ($this->cronRepository->getPluginJobs(true) as $item) {
77  // #18411 - we are NOT using the initial job data as it might be outdated at this point
78  $this->runJob($item[0], $actor);
79  }
80 
81  $this->logger->info('CRON - batch end');
82  }
static formatDate(ilDateTime $date, bool $a_skip_day=false, bool $a_include_wd=false, bool $include_seconds=false)
const IL_CAL_UNIX
static _lookupValue(string $a_module, string $a_keyword)
runJob(ilCronJob $job, ilObjUser $actor, ?array $jobData=null, bool $isManualExecution=false)
Run single cron job (internal)
static _getHttpPath()
static setUseRelativeDates(bool $a_status)
set use relative dates
+ Here is the call graph for this function:

◆ runJob()

ilCronManagerImpl::runJob ( ilCronJob  $job,
ilObjUser  $actor,
?array  $jobData = null,
bool  $isManualExecution = false 
)
private

Run single cron job (internal)

Definition at line 110 of file class.ilCronManagerImpl.php.

References Vendor\Package\$e, ilCronJobResult\CODE_SUPPOSED_CRASH, deactivateJob(), ilCronJob\getId(), getMicrotime(), ILIAS\Repository\int(), ilCronJob\isDue(), ILIAS\Repository\logger(), ilCronJob\run(), ilCronJob\setDateTimeProvider(), ilCronJobResult\STATUS_CRASHED, ilCronJobResult\STATUS_INVALID_CONFIGURATION, and ilStr\subStr().

Referenced by runActiveJobs(), and runJobManual().

110  : bool
111  {
112  $did_run = false;
113 
114  if (null === $jobData) {
115  // aquire "fresh" job (status) data
116  $jobsData = $this->cronRepository->getCronJobData($job->getId());
117  $jobData = array_pop($jobsData);
118  }
119 
120  $job->setDateTimeProvider(function (): DateTimeImmutable {
121  return $this->clock_factory->system()->now();
122  });
123 
124  // already running?
125  if ($jobData['alive_ts']) {
126  $this->logger->info('CRON - job ' . $jobData['job_id'] . ' still running');
127 
128  $cut = 60 * 60 * 3;
129 
130  // is running (and has not pinged) for 3 hours straight, we assume it crashed
131  if ($this->clock_factory->system()->now()->getTimestamp() - ((int) $jobData['alive_ts']) > $cut) {
132  $this->cronRepository->updateRunInformation($jobData['job_id'], 0, 0);
133  $this->deactivateJob($job, $actor); // #13082
134 
135  $result = new ilCronJobResult();
136  $result->setStatus(ilCronJobResult::STATUS_CRASHED);
137  $result->setCode(ilCronJobResult::CODE_SUPPOSED_CRASH);
138  $result->setMessage('Cron job deactivated because it has been inactive for 3 hours');
139 
140  $this->cronRepository->updateJobResult(
141  $job,
142  $this->clock_factory->system()->now(),
143  $actor,
144  $result,
145  $isManualExecution
146  );
147 
148  $this->logger->info('CRON - job ' . $jobData['job_id'] . ' deactivated (assumed crash)');
149  }
150  } // initiate run?
151  elseif ($job->isDue(
152  $jobData['job_result_ts'] ? (new DateTimeImmutable(
153  '@' . $jobData['job_result_ts']
154  ))->setTimezone($this->clock_factory->system()->now()->getTimezone()) : null,
155  is_numeric($jobData['schedule_type']) ? CronJobScheduleType::tryFrom((int) $jobData['schedule_type']) : null,
156  $jobData['schedule_value'] ? (int) $jobData['schedule_value'] : null,
157  $isManualExecution
158  )) {
159  $this->logger->info('CRON - job ' . $jobData['job_id'] . ' started');
160 
161  $this->cronRepository->updateRunInformation(
162  $jobData['job_id'],
163  $this->clock_factory->system()->now()->getTimestamp(),
164  $this->clock_factory->system()->now()->getTimestamp()
165  );
166 
167  $ts_in = $this->getMicrotime();
168  try {
169  $result = $job->run();
170  } catch (Throwable $e) {
171  $result = new ilCronJobResult();
172  $result->setStatus(ilCronJobResult::STATUS_CRASHED);
173  $result->setMessage(
174  ilStr::subStr(sprintf('Exception: %s / %s', $e->getMessage(), $e->getTraceAsString()), 0, 400)
175  );
176 
177  $this->logger->error($e->getMessage());
178  $this->logger->error($e->getTraceAsString());
179  } finally {
180  $ts_dur = $this->getMicrotime() - $ts_in;
181  }
182 
183  if ($result->getStatus() === ilCronJobResult::STATUS_INVALID_CONFIGURATION) {
184  $this->deactivateJob($job, $actor);
185  $this->logger->info('CRON - job ' . $jobData['job_id'] . ' invalid configuration');
186  } else {
187  // success!
188  $did_run = true;
189  }
190 
191  $result->setDuration($ts_dur);
192 
193  $this->cronRepository->updateJobResult(
194  $job,
195  $this->clock_factory->system()->now(),
196  $actor,
197  $result,
198  $isManualExecution
199  );
200  $this->cronRepository->updateRunInformation($jobData['job_id'], 0, 0);
201 
202  $this->logger->info('CRON - job ' . $jobData['job_id'] . ' finished');
203  } else {
204  $this->logger->info('CRON - job ' . $jobData['job_id'] . ' returned status inactive');
205  }
206 
207  return $did_run;
208  }
setDateTimeProvider(?Closure $date_time_provider)
isDue(?DateTimeImmutable $last_run, ?CronJobScheduleType $schedule_type, ?int $schedule_value, bool $is_manually_executed=false)
static subStr(string $a_str, int $a_start, ?int $a_length=null)
Definition: class.ilStr.php:24
final const STATUS_INVALID_CONFIGURATION
deactivateJob(ilCronJob $job, ilObjUser $actor, bool $wasManuallyExecuted=false)
final const CODE_SUPPOSED_CRASH
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ runJobManual()

ilCronManagerImpl::runJobManual ( string  $jobId,
ilObjUser  $actor 
)

Implements ilCronManager.

Definition at line 84 of file class.ilCronManagerImpl.php.

References ILIAS\Repository\logger(), and runJob().

84  : bool
85  {
86  $result = false;
87 
88  $this->logger->info('CRON - manual start (' . $jobId . ')');
89 
90  $job = $this->cronRepository->getJobInstanceById($jobId);
91  if ($job instanceof ilCronJob) {
92  if ($job->isManuallyExecutable()) {
93  $result = $this->runJob($job, $actor, null, true);
94  } else {
95  $this->logger->info('CRON - job ' . $jobId . ' is not intended to be executed manually');
96  }
97  } else {
98  $this->logger->info('CRON - job ' . $jobId . ' seems invalid or is inactive');
99  }
100 
101  $this->logger->info('CRON - manual end (' . $jobId . ')');
102 
103  return $result;
104  }
runJob(ilCronJob $job, ilObjUser $actor, ?array $jobData=null, bool $isManualExecution=false)
Run single cron job (internal)
+ Here is the call graph for this function:

The documentation for this class was generated from the following file: