['onTerminate', -64]]; } /** * Hebt die Laufzeitgrenze an - und senkt sie nie. * * `set_time_limit()` setzt die Grenze, es verlaengert nicht: auf einem Prozess ohne Grenze * (Konsole, Testlauf, Hoster mit `max_execution_time = 0`) macht ein fester Wert aus * "unbegrenzt" plötzlich "noch so viele Sekunden" - und der Prozess stirbt spaeter an einer * Stelle, die mit Aufgaben nichts zu tun hat. */ private function raiseTimeLimit(int $seconds): void { $current = (int) ini_get('max_execution_time'); if ($current > 0 && $current < $seconds) { @set_time_limit($seconds); } } public function onTerminate(TerminateEvent $event): void { $request = $event->getRequest(); if ($request->attributes->getBoolean(self::HANDLED)) { return; } $path = $request->getPathInfo(); if (1 === preg_match(self::IGNORED, $path)) { return; } // Während eines Updates läuft nichts: die Dateien sind vielleicht schon die neuen und // die Datenbank noch die alte. Und vor der Installation gibt es keine Tabelle. if (is_file($this->projectDir.'/'.Updater::MAINTENANCE_FILE) || !is_file($this->projectDir.'/'.InstallSubscriber::MARKER)) { return; } $admin = str_starts_with($path, '/'.$this->adminPath); $state = $this->scheduler->fastState(); if (!($admin ? $state['admin'] : $state['traffic'])) { return; } if (null !== $state['next'] && $state['next'] > time()) { return; } try { // Die Antwort ist raus; ein abgebrochener Aufruf soll die Arbeit trotzdem zu Ende // bringen, sonst bliebe eine Aufgabe auf halbem Weg mit gesetzter Sperre liegen. @ignore_user_abort(true); $this->raiseTimeLimit($this->budget + 60); $this->scheduler->runDue($admin ? 'verwaltung' : 'besuch', $this->limit, $this->budget); } catch (\Throwable) { // Eine Aufgabe darf niemals eine Website kaputtmachen. Was schiefging, steht in der // Zeile der Aufgabe und in var/tasks.log - hier ist niemand mehr, dem man es sagen // könnte: die Antwort ist längst verschickt. } } }