From 184c39d829517747cfaf931ffc67ace0a6656495 Mon Sep 17 00:00:00 2001 From: Patrick Niebeling Date: Thu, 13 Aug 2026 15:18:22 +0200 Subject: [PATCH] Document that the time_sensitive column has to be reset once Shipping the TIME_SENSITIVE change is not enough for instances that already ran the job: getNext() filters on the time_sensitive column of oc_jobs, and JobList::setLastRun() only ever sets it to TIME_INSENSITIVE -- there is no else branch, and JobList::add() writes the column only when inserting, so re-registering an existing job on app update or app:enable leaves the stamp in place. Document the one-off UPDATE (and the occ-only alternative) in the README troubleshooting section and in CLAUDE.md. --- CLAUDE.md | 17 +++++++++++++++++ README.md | 24 ++++++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/CLAUDE.md b/CLAUDE.md index 883d8bb..484d3db 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -24,6 +24,23 @@ The filter-matching logic (`WorkflowRunner::cardMatchesFilters()`, `::isOverdue( **The job must stay `IJob::TIME_SENSITIVE`.** It was `TIME_INSENSITIVE` at first, which looked harmless and was not: `OC\Core\Service\CronService::runCli()` reads `maintenance_window_start` (default `100`, i.e. unset) and, whenever the current UTC hour is outside `[start, start+4]`, calls `jobList->getNext($onlyTimeSensitive = true)` — time-insensitive jobs are then skipped for the other 20 hours of the day. On an instance with a maintenance window configured (Nextcloud's admin overview nags admins into setting one) the job simply never ran, showing `last_run = 1970-01-01` in `occ background-job:list` indefinitely. Note this gate only exists in `runCli()`, so it doesn't apply to ajax/webcron mode, and passing job classes explicitly (`occ background-job:worker ''`) bypasses it — which is exactly why manual testing can look fine while cron does nothing. +**Changing the sensitivity in code does not fix an already-registered job.** `getNext()` filters on the `time_sensitive` *column* of `oc_jobs`, and `JobList::setLastRun()` is a one-way ratchet: + +```php +if ($job instanceof TimedJob && !$job->isTimeSensitive()) { + $query->set('time_sensitive', $query->createNamedParameter(IJob::TIME_INSENSITIVE)); +} +``` + +There is no `else`. Once a job has run while declaring itself insensitive, the row is stamped `TIME_INSENSITIVE` for good — and nothing resets it: `JobList::add()` only writes the column in its *insert* branch, and re-registering an existing job (app update, `app:enable`) takes the *update* branch, which leaves it alone. So after deploying the `TIME_SENSITIVE` change, an existing instance still needs its row fixed once: + +```sql +UPDATE oc_jobs SET time_sensitive = 0 + WHERE class = 'OCA\\WorkflowDeckAutomation\\BackgroundJob\\RunWorkflowsJob'; +``` + +or, without DB access, `occ background-job:delete ` followed by `occ app:disable workflow_deck_automation && occ app:enable workflow_deck_automation` to get a freshly inserted row. Fresh installs are unaffected. + To debug this job on a server: `occ background-job:list --class ''` for its id and last run, then `occ background-job:execute --force-execute` to run it right now regardless of the interval. `occ background-job:worker` takes **job classes**, not an app id. ## Registration is declarative, not Bootstrap-based diff --git a/README.md b/README.md index 927da5a..915c274 100644 --- a/README.md +++ b/README.md @@ -52,6 +52,30 @@ Das Prüfintervall des Hintergrundjobs lässt sich in der `config.php` setzen (W Zu beachten: Das ist eine *Untergrenze* für den Abstand zwischen zwei Läufen, keine Garantie. Nextclouds Cron selbst läuft üblicherweise nur alle 5 Minuten — ein Intervall von 60 Sekunden führt also nur dann zu minütlichen Läufen, wenn der System-Cron entsprechend häufig ausgeführt wird. +### Der Job läuft nur nachts bzw. gar nicht + +Der Job ist als `TIME_SENSITIVE` deklariert und läuft damit rund um die Uhr. Nextcloud merkt sich die Zeitsensitivität aber zusätzlich in der Spalte `time_sensitive` der Tabelle `oc_jobs`, und `JobList::setLastRun()` setzt sie nur in eine Richtung — von „zeitkritisch" auf „unkritisch", nie zurück. Wer eine ältere Version dieser App installiert hatte (bis einschließlich v0.1.0 war der Job `TIME_INSENSITIVE`), hat diesen Stempel noch in der Datenbank. Er wird weder durch ein App-Update noch durch `app:enable` zurückgesetzt. + +Symptom: Ist in der `config.php` ein `maintenance_window_start` gesetzt, läuft der Job nur in diesem 4-Stunden-Fenster und den Rest des Tages gar nicht. + +Einmalig korrigieren: + +```sql +UPDATE oc_jobs SET time_sensitive = 0 + WHERE class = 'OCA\\WorkflowDeckAutomation\\BackgroundJob\\RunWorkflowsJob'; +``` + +Ohne Datenbankzugriff geht es auch über `occ`, indem der Job gelöscht und durch Aus-/Einschalten der App neu registriert wird: + +```bash +php occ background-job:list --class 'OCA\WorkflowDeckAutomation\BackgroundJob\RunWorkflowsJob' +php occ background-job:delete +php occ app:disable workflow_deck_automation +php occ app:enable workflow_deck_automation +``` + +Neuinstallationen sind nicht betroffen. + ## Entwicklung Voraussetzungen: PHP 8.2+, Composer, Node.js 24+, npm 11+.