Fassung 1.6.0: der Aufgabenplan wird veroeffentlicht
Wiederkehrende Aufgaben ohne Cronjob (ADR 073): Sicherung, Statistik kuerzen, geplante Veroeffentlichung, Updatepruefung und Aufraeumen laufen als Plan in der Tabelle scheduled_task - eine Zeile je Aufgabe mit Faelligkeit, Sperre und letztem Ergebnis. Auf geteiltem Hosting gibt es oft keinen Cronjob; der Plan haengt stattdessen an Anfragen und an einem Takt aus dem geoeffneten Backend. Diese Arbeit entstand in einer parallel laufenden Sitzung und lag bis hierher unveroeffentlicht im Arbeitsverzeichnis: die Releases 1.5.0 bis 1.5.5 wurden bewusst aus dem jeweiligen Tag gebaut und enthielten sie deshalb nicht. Vor der Veroeffentlichung geprueft, nicht bloss eingepackt: - phpunit 452/452, npm test 28/28, npm run test:editor vollstaendig. - Die Migration 20260914000100 legt nur die Tabelle scheduled_task an und nimmt sie beim Zurueckrollen wieder weg. Sie fasst keine bestehenden Daten an. - Seit einer Stunde keine Schreibzugriffe der anderen Sitzung mehr. Dabei zwei Fehler behoben: - config/services.yaml verwendet !tagged_iterator. Das ist gueltiges Symfony, aber "lint:yaml config" kennt eigene Tags nur mit --parse-tags und gab 1 zurueck - der CI-Lauf waere daran gescheitert. Flag ergaenzt. - AdminHeadersSubscriber.php (aus 1.5.3) entsprach nicht dem Stil von php-cs-fixer; composer lint gab 8 zurueck. Behoben. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
d1ac9d760b
commit
05ea703655
35 files changed
+2229
-13
No files matched your search
@@ -446,6 +446,11 @@ details.card > summary:hover { background: #fafbf8 }
|
||||
.theme-table td input[type=color] { width: 52px }
|
||||
.theme-table .weights-cell { white-space: nowrap }
|
||||
.redirect-table td { padding: 8px 12px 8px 0; font-size: 12px }
|
||||
/* Der Aufgabenplan: die erste Spalte traegt Text, die schmalen tragen Zahlen und Schalter. */
|
||||
.tasks-table td:first-child { min-width: 220px; max-width: 340px }
|
||||
.tasks-table td input[type=number] { width: 92px }
|
||||
.tasks-table td .field-help { margin-top: 4px }
|
||||
.tasks-table .row-actions, .tasks-table td:last-child { white-space: nowrap }
|
||||
/* Headings inside a card separate its parts without a second border. */
|
||||
.card-body .section-head { margin: 28px 0 12px }
|
||||
.card-body .section-head:first-child { margin-top: 14px }
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Der Takt des geöffneten Backends.
|
||||
*
|
||||
* Auf einer Website ohne Besucher gibt es keinen Auslöser für wiederkehrende Aufgaben - außer
|
||||
* dem Menschen, der gerade in der Verwaltung arbeitet. Dieses Skript klopft in seinem Namen alle
|
||||
* 60 Sekunden an; der Server entscheidet, ob überhaupt etwas fällig ist.
|
||||
*
|
||||
* Drei Eigenschaften, die es unauffällig machen:
|
||||
*
|
||||
* - Es fragt nur, während der Reiter sichtbar ist. Ein vergessener Hintergrundreiter soll keine
|
||||
* Sitzung endlos offen halten und keine Anfragen erzeugen, die niemand sehen will.
|
||||
* - Es fragt nie zwei Mal gleichzeitig: eine laufende Anfrage blockiert die nächste.
|
||||
* - Ein Fehlschlag ist kein Ereignis. Kein Hinweis, keine Meldung - beim nächsten Takt wieder.
|
||||
*/
|
||||
(function () {
|
||||
var endpoint = document.querySelector('meta[name="kant-tick"]');
|
||||
var token = document.querySelector('meta[name="kant-tick-token"]');
|
||||
if (!endpoint || !token || !window.fetch) {
|
||||
return;
|
||||
}
|
||||
var busy = false;
|
||||
|
||||
function tick() {
|
||||
if (busy || document.visibilityState !== 'visible') {
|
||||
return;
|
||||
}
|
||||
busy = true;
|
||||
var body = new FormData();
|
||||
body.append('_csrf_token', token.content);
|
||||
fetch(endpoint.content, { method: 'POST', body: body, credentials: 'same-origin' })
|
||||
.catch(function () {})
|
||||
.then(function () {
|
||||
busy = false;
|
||||
});
|
||||
}
|
||||
|
||||
// Der erste Takt kommt verzögert: beim Seitenaufbau hat der Browser Wichtigeres zu tun.
|
||||
window.setTimeout(tick, 5000);
|
||||
window.setInterval(tick, 60000);
|
||||
document.addEventListener('visibilitychange', function () {
|
||||
if (document.visibilityState === 'visible') {
|
||||
tick();
|
||||
}
|
||||
});
|
||||
})();
|
||||
Reference in new issue
Block a user