diff options
| author | Simon Rettberg | 2025-02-13 15:49:13 +0100 |
|---|---|---|
| committer | Simon Rettberg | 2025-02-13 15:49:13 +0100 |
| commit | b3d090a0d9551586a06e1ccddcabc155818939de (patch) | |
| tree | 2fc444ed2da24d9f1c3fa51e18b7420e4607912e /modules-available | |
| parent | [vmstore] Minor tweak to initial wait (diff) | |
| download | slx-admin-b3d090a0d9551586a06e1ccddcabc155818939de.tar.gz slx-admin-b3d090a0d9551586a06e1ccddcabc155818939de.tar.xz slx-admin-b3d090a0d9551586a06e1ccddcabc155818939de.zip | |
[locationinfo] Change $forceCached to a flexible timeout approach
We can now give a precise deadline until which the backend(s) will try
to update stale calendar data, and just return cached data for all the
entries where no time was left.
Diffstat (limited to 'modules-available')
9 files changed, 47 insertions, 25 deletions
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Client.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Client.php index c25d7ecc..3a640f99 100644 --- a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Client.php +++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Client.php @@ -198,6 +198,11 @@ class Client $this->soap = null; } + public function setCurlOption(int $key, $value): void + { + $this->curl_options[$key] = $value; + } + /** * Sets the impersonation property * diff --git a/modules-available/locationinfo/inc/coursebackend.inc.php b/modules-available/locationinfo/inc/coursebackend.inc.php index ea1bebac..95bef8ff 100644 --- a/modules-available/locationinfo/inc/coursebackend.inc.php +++ b/modules-available/locationinfo/inc/coursebackend.inc.php @@ -147,7 +147,7 @@ abstract class CourseBackend * and has the schedule array as value. A schedule array contains an array in this format: * ["start"=>'JJJJ-MM-DD"T"HH:MM:SS',"end"=>'JJJJ-MM-DD"T"HH:MM:SS',"title"=>string] */ - protected abstract function fetchSchedulesInternal(array $requestedRoomIds): array; + protected abstract function fetchSchedulesInternal(array $requestedRoomIds, ?int $deadline): array; /** * In case you want to sanitize or otherwise mangle a property for your backend, @@ -177,7 +177,7 @@ abstract class CourseBackend * @param array $requestedLocationIds array of room ID to fetch * @return array array containing the timetables as value and roomid as key as result, or false on error */ - public final function fetchSchedule(array $requestedLocationIds): array + public final function fetchSchedule(array $requestedLocationIds, ?int $deadline): array { if (empty($requestedLocationIds)) return array(); @@ -231,7 +231,7 @@ abstract class CourseBackend 'slocs' => array_values($remoteIds), ]); } - $backendResponse = $this->fetchSchedulesInternal(array_unique($remoteIds)); + $backendResponse = $this->fetchSchedulesInternal(array_unique($remoteIds), $deadline); // Fetching might have taken a while, get current time again $NOW = time(); diff --git a/modules-available/locationinfo/inc/coursebackend/coursebackend_davinci.inc.php b/modules-available/locationinfo/inc/coursebackend/coursebackend_davinci.inc.php index 786ab459..44879caa 100644 --- a/modules-available/locationinfo/inc/coursebackend/coursebackend_davinci.inc.php +++ b/modules-available/locationinfo/inc/coursebackend/coursebackend_davinci.inc.php @@ -70,7 +70,7 @@ class CourseBackend_Davinci extends CourseBackend * @param \DateTime $endDate end date of range to fetch * @return false|string if successful the array representation of the timetable */ - private function fetchRoomRaw(string $roomId, DateTime $startDate, DateTime $endDate) + private function fetchRoomRaw(string $roomId, DateTime $startDate, DateTime $endDate, int $timeout) { $url = $this->location . "content=xml&type=room&name=" . urlencode($roomId) . "&startdate=" . $startDate->format('d.m.Y') . "&enddate=" . $endDate->format('d.m.Y'); @@ -83,7 +83,7 @@ class CourseBackend_Davinci extends CourseBackend CURLOPT_SSL_VERIFYHOST => $this->verifyHostname ? 2 : 0, CURLOPT_SSL_VERIFYPEER => $this->verifyCert ? 1 : 0, CURLOPT_URL => $url, - CURLOPT_TIMEOUT => 15, + CURLOPT_TIMEOUT => min(60, $timeout), CURLOPT_CONNECTTIMEOUT => 3, ); @@ -97,7 +97,7 @@ class CourseBackend_Davinci extends CourseBackend } - public function fetchSchedulesInternal(array $requestedRoomIds): array + public function fetchSchedulesInternal(array $requestedRoomIds, ?int $deadline): array { $startDate = new DateTime('last Monday 0:00'); $endDate = new DateTime('+14 days 0:00'); @@ -105,7 +105,10 @@ class CourseBackend_Davinci extends CourseBackend $upper = (int)$endDate->format('Ymd'); $schedules = []; foreach ($requestedRoomIds as $roomId) { - $return = $this->fetchRoomRaw($roomId, $startDate, $endDate); + $timeout = ($deadline ?? PHP_INT_MAX) - time(); + if ($timeout <= 1) + break; + $return = $this->fetchRoomRaw($roomId, $startDate, $endDate, $deadline); if ($return === false) { continue; } diff --git a/modules-available/locationinfo/inc/coursebackend/coursebackend_dummy.inc.php b/modules-available/locationinfo/inc/coursebackend/coursebackend_dummy.inc.php index 4588bf7c..8ca72e92 100644 --- a/modules-available/locationinfo/inc/coursebackend/coursebackend_dummy.inc.php +++ b/modules-available/locationinfo/inc/coursebackend/coursebackend_dummy.inc.php @@ -82,13 +82,11 @@ class CourseBackend_Dummy extends CourseBackend /** * Internal version of fetch, to be overridden by subclasses. - * - * @param $requestedRoomIds array with local ID as key and serverId as value * @return array a recursive array that uses the roomID as key * and has the schedule array as value. A schedule array contains an array in this format: * ["start"=>'YYYY-MM-DD<T>HH:MM:SS',"end"=>'YYYY-MM-DD<T>HH:MM:SS',"title"=>string] */ - public function fetchSchedulesInternal(array $requestedRoomIds): array + public function fetchSchedulesInternal(array $requestedRoomIds, ?int $deadline): array { $a = array(); foreach ($requestedRoomIds as $id) { diff --git a/modules-available/locationinfo/inc/coursebackend/coursebackend_exchange.inc.php b/modules-available/locationinfo/inc/coursebackend/coursebackend_exchange.inc.php index df33dadd..b4a35139 100755 --- a/modules-available/locationinfo/inc/coursebackend/coursebackend_exchange.inc.php +++ b/modules-available/locationinfo/inc/coursebackend/coursebackend_exchange.inc.php @@ -150,13 +150,11 @@ class CourseBackend_Exchange extends CourseBackend /** * Internal version of fetch, to be overridden by subclasses. - * - * @param $requestedRoomIds array with local ID as key and serverId as value * @return array a recursive array that uses the roomID as key * and has the schedule array as value. A schedule array contains an array in this format: * ["start"=>'JJJJ-MM-DD HH:MM:SS',"end"=>'JJJJ-MM-DD HH:MM:SS',"title"=>string] */ - protected function fetchSchedulesInternal(array $requestedRoomIds): array + protected function fetchSchedulesInternal(array $requestedRoomIds, ?int $deadline): array { $startDate = new DateTime('last Monday 0:00'); $endDate = new DateTime('+14 days 0:00'); @@ -164,6 +162,12 @@ class CourseBackend_Exchange extends CourseBackend $schedules = []; foreach ($requestedRoomIds as $roomId) { + if ($deadline !== null) { + $timeout = $deadline - time(); + if ($timeout <= 1) + break; + $client->setCurlOption(CURLOPT_TIMEOUT, min($timeout, 60)); + } try { $items = $this->findEventsForRoom($client, $startDate, $endDate, $roomId); } catch (Exception $e) { @@ -241,7 +245,7 @@ class CourseBackend_Exchange extends CourseBackend $client->setCurlOptions(array( CURLOPT_SSL_VERIFYPEER => $this->verifyHostname ? 2 : 0, CURLOPT_SSL_VERIFYHOST => $this->verifyCert ? 1 : 0, - CURLOPT_TIMEOUT => 15, + CURLOPT_TIMEOUT => 60, CURLOPT_CONNECTTIMEOUT => 3, )); diff --git a/modules-available/locationinfo/inc/coursebackend/coursebackend_hisinone.inc.php b/modules-available/locationinfo/inc/coursebackend/coursebackend_hisinone.inc.php index 55d5ed4b..9128288d 100644 --- a/modules-available/locationinfo/inc/coursebackend/coursebackend_hisinone.inc.php +++ b/modules-available/locationinfo/inc/coursebackend/coursebackend_hisinone.inc.php @@ -59,7 +59,7 @@ class CourseBackend_HisInOne extends ICalCourseBackend // So we just try a bunch and see if anything works. Even if this fails, using // the backend should work, given the URL is actually correct. foreach ([60, 100, 5, 10, 50, 110, 200, 210, 250, 300, 333, 500, 1000, 2000] as $roomId) { - if ($this->downloadIcal($roomId) !== null) + if ($this->downloadIcal($roomId, 60) !== null) return true; } return false; diff --git a/modules-available/locationinfo/inc/coursebackend/coursebackend_ical.inc.php b/modules-available/locationinfo/inc/coursebackend/coursebackend_ical.inc.php index f1791c4e..37d9d9d8 100644 --- a/modules-available/locationinfo/inc/coursebackend/coursebackend_ical.inc.php +++ b/modules-available/locationinfo/inc/coursebackend/coursebackend_ical.inc.php @@ -39,7 +39,7 @@ class CourseBackend_ICal extends ICalCourseBackend return false; if (empty($this->testId)) return true; - return ($this->downloadIcal($this->testId) !== null); + return ($this->downloadIcal($this->testId, 60) !== null); } public function getCacheTime(): int diff --git a/modules-available/locationinfo/inc/icalcoursebackend.inc.php b/modules-available/locationinfo/inc/icalcoursebackend.inc.php index 838d18b7..6d9bbeef 100644 --- a/modules-available/locationinfo/inc/icalcoursebackend.inc.php +++ b/modules-available/locationinfo/inc/icalcoursebackend.inc.php @@ -38,7 +38,7 @@ abstract class ICalCourseBackend extends CourseBackend * @param callable $errorFunc * @return ICalEvent[]|null all events for this room in the range -7 days to +7 days, or NULL on error */ - protected function downloadIcal(string $roomId): ?array + protected function downloadIcal(string $roomId, int $timeout): ?array { if (!$this->isOK()) return null; @@ -63,7 +63,7 @@ abstract class ICalCourseBackend extends CourseBackend CURLOPT_SSL_VERIFYHOST => $this->verifyHostname ? 2 : 0, CURLOPT_SSL_VERIFYPEER => $this->verifyCert ? 1 : 0, CURLOPT_URL => str_replace('%ID%', $roomId, $this->location), - CURLOPT_TIMEOUT => 60, + CURLOPT_TIMEOUT => min(60, $timeout), CURLOPT_CONNECTTIMEOUT => 4, ]; if ($this->authMethod !== 'NONE' && defined('CURLAUTH_' . $this->authMethod)) { @@ -90,14 +90,17 @@ abstract class ICalCourseBackend extends CourseBackend return $ical->events(); } - public function fetchSchedulesInternal(array $requestedRoomIds): array + public function fetchSchedulesInternal(array $requestedRoomIds, ?int $deadline): array { if (empty($requestedRoomIds) || !$this->isOK()) { return array(); } $tTables = []; foreach ($requestedRoomIds as $roomId) { - $data = $this->downloadIcal($roomId); + $timeout = ($deadline ?? PHP_INT_MAX) - time(); + if ($timeout <= 1) + break; + $data = $this->downloadIcal($roomId, $timeout); if ($data === null) { $this->addError("Downloading ical for $roomId failed", false); continue; diff --git a/modules-available/locationinfo/inc/locationinfo.inc.php b/modules-available/locationinfo/inc/locationinfo.inc.php index 64010c16..2ce557f4 100644 --- a/modules-available/locationinfo/inc/locationinfo.inc.php +++ b/modules-available/locationinfo/inc/locationinfo.inc.php @@ -141,16 +141,17 @@ class LocationInfo * Gets the calendar of the given ids. * * @param int[] $idList list with the location ids. + * @param ?int $deadline null = no timeout, otherwise a unix timestamp until which we expect function to return * @return array Calendar. */ - public static function getCalendar(array $idList, bool $forceCached = false): array + public static function getCalendar(array $idList, ?int $deadline = null): array { if (empty($idList)) return []; $resultArray = array(); - if ($forceCached) { + if ($deadline !== null && $deadline <= time() + 1) { $res = Database::simpleQuery("SELECT locationid, calendar FROM locationinfo_locationconfig WHERE Length(calendar) > 10 AND lastcalendarupdate > UNIX_TIMESTAMP() - 86400*3"); foreach ($res as $row) { @@ -194,7 +195,7 @@ class LocationInfo $credentialsOk = $serverInstance->setCredentials($serverid, $server['credentials']); if ($credentialsOk) { - $calendarFromBackend = $serverInstance->fetchSchedule($server['idlist']); + $calendarFromBackend = $serverInstance->fetchSchedule($server['idlist'], $deadline); } else { $calendarFromBackend = array(); } @@ -211,11 +212,19 @@ class LocationInfo return $resultArray; } - public static function getAllCalendars(bool $forceCached): array + /** + * Get all calendars. Can update or fetch from cache. If $deadline is NULL, all calendars that are stale will + * be fetched from the according backends. Otherwise, $deadline is expected to be a UNIX TIMESTAMP until which + * we request the function to return, trying to update as many stale calendars as possible during that time, + * returning cached values for all that weren't updated. Passing a timestamp in the past (e.g. 0) ensures + * that all calendars will be served from cache, regardless of age. + * @param ?int $deadline null = no timeout, otherwise a unix timestamp until which we expect function to return + */ + public static function getAllCalendars(?int $deadline = null): array { $locations = Database::queryColumnArray("SELECT locationid FROM location"); $calendars = []; - foreach (LocationInfo::getCalendar($locations, $forceCached) as $cal) { + foreach (LocationInfo::getCalendar($locations, $deadline) as $cal) { if (empty($cal['calendar'])) continue; $calendars[$cal['id']] = $cal['calendar']; |
