ILIAS  trunk Revision v13.0_alpha-52-g21c366bbdd4
AsyncTaskManager.php
Go to the documentation of this file.
1<?php
2
20
27
29{
30 public const CMD_START_WORKER = 'startBackgroundTaskWorker';
31
36 public function run(Bucket $bucket): void
37 {
38 global $DIC;
39
40 // check this before saving the bucket state to prevent an orphaned entry with 0%
41 if (!$DIC->settings()->get('soap_user_administration')) {
42 $DIC->logger()->bgtk()->warning("SOAP not enabled, fallback to sync version");
43 $sync_manager = new SyncTaskManager($this->persistence);
44 $sync_manager->run($bucket);
45 return;
46 }
47
48 $bucket->setState(State::SCHEDULED);
49 $bucket->setCurrentTask($bucket->getTask());
50 $DIC->backgroundTasks()->persistence()->saveBucketAndItsTasks($bucket);
51
52 $DIC->logger()->bgtk()->info("Trying to call webserver");
53
54 // Call SOAP-Server
55 $soap_client = new \ilSoapClient();
56 $soap_client->setResponseTimeout(1);
57 $soap_client->enableWSDL(true);
58 $soap_client->init();
59 $session_id = session_id();
60 $client_id = $DIC->http()->wrapper()->cookie()->retrieve(
61 'ilClientId',
62 $DIC->refinery()->byTrying([
63 $DIC->refinery()->kindlyTo()->string(),
64 $DIC->refinery()->always(
65 defined('CLIENT_ID') ? CLIENT_ID : null
66 )
67 ])
68 );
69
70 try {
71 $soap_client->call(self::CMD_START_WORKER, [
72 $session_id . '::' . $client_id,
73 ]);
74 } catch (\Throwable $t) {
75 $DIC->logger()->bgtk()->warning($t->getMessage());
76 $DIC->logger()->bgtk()->warning("Calling webserver failed, fallback to sync version");
77 $sync_manager = new SyncTaskManager($this->persistence);
78 $sync_manager->run($bucket);
79 return;
80 }
81 $DIC->logger()->bgtk()->info("Calling webserver successful");
82 }
83
87 public function runAsync(): ?bool
88 {
89 global $DIC, $ilIliasIniFile;
90
91 $n_of_tasks = $ilIliasIniFile->readVariable("background_tasks", "number_of_concurrent_tasks");
92 $n_of_tasks = $n_of_tasks ?: 5;
93
94 $DIC->logger()->bgtk()->info("Starting background job.");
95 $persistence = $DIC->backgroundTasks()->persistence();
96
97 // TODO search over all clients.
98 $MAX_PARALLEL_JOBS = $n_of_tasks;
99 if (count($persistence->getBucketIdsByState(State::RUNNING)) >= $MAX_PARALLEL_JOBS) {
100 $DIC->logger()->bgtk()->info("Too many running jobs, worker going down.");
101
102 return null;
103 }
104
105 $ids = [];
106 while (true) {
107 if ($ids === []) {
108 $ids = $persistence->getBucketIdsByState(State::SCHEDULED);
109 if ($ids === []) {
110 break;
111 }
112 }
113
114 $bucket_id = (int) array_shift($ids);
115 try {
116 $bucket = $persistence->loadBucket($bucket_id);
117 } catch (BucketNotFoundException $e) {
118 // Another worker already removed this bucket. Keep the remaining ids.
119 $DIC->logger()->bgtk()->info(
120 "Bucket with id $bucket_id no longer exists, skipping it."
121 );
122 continue;
123 } catch (SerializationException $e) {
124 // Missing or corrupt entries in il_bt_task / il_bt_value. Remove the bucket,
125 // otherwise it would be picked up again and again.
126 $DIC->logger()->bgtk()->warning(
127 "Could not load bucket with id $bucket_id, skipping and deleting it: " . $e->getMessage()
128 );
129 try {
130 $persistence->deleteBucketById($bucket_id);
131 } catch (\Throwable $t) {
132 $DIC->logger()->bgtk()->error(
133 "Could not delete bucket with id $bucket_id, worker going down: " . $t->getMessage()
134 );
135 break;
136 }
137 continue;
138 } catch (\Throwable $t) {
139 // A database failure or a bucket that is still being saved must not be deleted.
140 $DIC->logger()->bgtk()->error(
141 "Could not load bucket with id $bucket_id, worker going down: " . $t->getMessage()
142 );
143 break;
144 }
145 // A job may take long enough for the queue to change. Reload after it finishes.
146 $ids = [];
147 $observer = new PersistingObserver($bucket, $persistence);
148 $task = $bucket->getTask();
149
150 try {
151 $this->executeTask($task, $observer);
152 $bucket->setState(State::FINISHED);
153 $this->persistence->updateBucket($bucket);
155 $bucket->setState(State::FINISHED);
156 $this->persistence->deleteBucket($bucket);
158 // We're okay!
159 $this->persistence->saveBucketAndItsTasks($bucket);
160 } catch (\Throwable $e) {
161 $persistence->deleteBucket($bucket);
162 $DIC->logger()->bgtk()->info("Exception while async computing: "
163 . $e->getMessage());
164 $DIC->logger()->bgtk()->info("Stack Trace: "
165 . $e->getTraceAsString());
166 }
167 }
168
169 $DIC->logger()->bgtk()->info("One worker going down because there's nothing left to do.");
170
171 return true;
172 }
173}
run(Bucket $bucket)
This will add an Observer of the Task and start running the task.
string $client_id
Definition: class.ilias.php:36
const CLIENT_ID
Definition: constants.php:41
executeTask(Task $task, Observer $observer)
Actually executes a task.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
global $DIC
Definition: shib_login.php:26
$ilIliasIniFile
Definition: server.php:39