enhancement
major
minor
defect
critical
major
minor
major
#30057
Administration of the React UI: scheduler (task list, run now, stop, activate/deactivate, cluster lock, run history) with one unified active/inactive switch per task
Split off #30047. Follow-up to #29767, related: #29108, #18518, #18690, #19415.
Context
The administration of the React UI is admin/admin.view.xml of tl-layout-view (sections Access control, Monitoring, System; further sections contributed by same-path overlays, see the developer article view-layer/overlays). The scheduler administration existed in the classic UI only (admin/technical/scheduler/schedulerView.layout.xml).
The scheduler knew too many ways to keep a task from running (#18518), which behaved differently:
- enabled in the task configuration (a disabled task could still be run manually),
- Scheduler.enable() / disable() (cluster node local, lost on restart),
- blocking by the administrator (blockTask() / unblockTask(), stored in the database; a blocked task could not be run manually),
- blocked-by-default in the task configuration (default of the blocking),
- blocking-allowed in the task configuration (whether the administrator may block the task at all).
Feature
One active/inactive switch per task. Every task is either active (scheduled according to its schedules) or inactive (never scheduled automatically). The configured enabled value is the default. An administrator can activate or deactivate every task; this choice is stored in the database, applies to the whole cluster and survives restarts. It is bound to the configured value it overrides: when an application update changes the configured enabled value of the task, the stored choice is dropped and the new configured value applies. "Reset to configured state" drops the stored choice explicitly. Activating, deactivating and resetting are written to the application log.
Run now starts immediately. "Run now" starts every task, also an inactive one, right away instead of in the next polling round of the scheduler (default: every 10 minutes). The end of a run (its result, the release of its cluster lock) is processed right after the run as well.
Scheduler view in the System section of the React administration (Administration → System → Scheduler):
- a table of the scheduler tasks (composite tasks with their subtasks) with active state (configured or set by an administrator), schedule, last and next run, last result, execution state and the cluster node holding the lock,
- commands, each offered only where it applies: Run now, Stop (while running, with confirmation; the stop request is logged with the user), Activate, Deactivate, Reset to configured state, Release cluster lock, Refresh, and Configuration, which opens the configuration of the scheduler and its tasks in System → Services,
- a detail page per task (address .../scheduler/task/<task name>) with its properties, its configuration including the schedules, and the history of its runs (result, start, end, duration, cluster node, message, warnings); a run opens a dialog with the full message, the warnings, the stack trace of an exception (monospaced, lines not wrapped, with a button copying it to the clipboard) and the run's log file for download.
Releasing a cluster lock (both UIs) is refused for a node-local or non-persistent task, a task without lock, and a lock held by this cluster node for a run still in progress here (such a lock is never stale). The confirmation points out the risk of running the task twice; the release is logged as warning with task, cluster node and the acting user (#18690).
The classic scheduler view uses the same switch: commands "Activate", "Deactivate" and "Reset to configured state" instead of block / unblock, and one column "Active" telling whether the state is configured or set by an administrator.
Preformatted multi-line text. The annotation <multi-line> of a string attribute has the option preformatted: the text is shown in a fixed-width font, its lines are not wrapped and long lines scroll horizontally, in the React and in the classic UI, editable and read-only (e.g. for stack traces, log excerpts, JSON). In the React UI a read-only preformatted value offers a button copying it to the clipboard (part CopyButton, replaceable by a customer component library).
Fixed on the way
- The scheduler thread waited on an AtomicBoolean monitor (#19415); it now waits on a lock condition, which also carries the wake-up.
- Tasks scheduled <on-startup/> (e.g. RefreshUsersTask, the user synchronization with LDAP) did not run directly after the application start, but only after the first polling interval of the scheduler (10 minutes in the engine configuration): every round of the dispatch thread, also the first one, waited for the polling interval before starting the due tasks. The first round now starts the due tasks right when the scheduler begins dispatching, i.e. when the application has started.
- React UI: a command was executed at the session revision of the window's previous request, so it did not see commits of other threads (e.g. "Refresh" still showed a task as "canceling" after its run had ended). The window is now brought to the latest committed state before a command (and an upload, and a navigation by URL) is executed.
- The test task InstructableTestTask reacts to a stop request and can write a log file for its runs (write-log-file).
Demo
tl-demo-react has demo tasks showing each situation: a long-running task (to stop), a failing task (stack trace), a task with warnings and a log file, a task inactive by configuration and a cluster-global task with cluster lock.
Verification
tl-demo-react (/view/, root / root1234), Administration → System → Scheduler; classic UI tl-demo, Administration → Tech. Administration → Steuerprogramm. Tests: TestScheduler (switch, stored choice, take-over of stored blocks, immediate start, cluster lock release and its refusal, log file), TestSchedulerOnStartup (an <on-startup/> task runs right after the dispatch start with a polling interval of one hour, a task not yet due does not), TestCommandSeesForeignCommit (React command sees a commit of another thread), vitest cases of the parts FieldValue, TextInput and CopyButton (TopLogic and MUI drawing).
Migration
- The task configuration property blocked-by-default is removed. Replace blocked-by-default="true" with enabled="false".
- The task configuration property blocking-allowed is removed without replacement; every task can be activated and deactivated by an administrator.
- Scheduler.enable(Task) / disable(Task) / isTaskEnabled(Task) / isEnabled(Task) and blockTask(Task) / unblockTask(Task) / isTaskBlocked(Task) are replaced by activate(Task) / deactivate(Task) / isActive(Task) / resetActive(Task). Scheduler.isBlockingAllowed(Task) and Task.isBlockingAllowed() are removed.
- Classic scheduler view: the command handlers blockTask / unblockTask are replaced by deactivateTask / activateTask (plus resetTaskActive); the classes moved from com.top_logic.util.sched.layout.block to com.top_logic.util.sched.layout.active. The table columns isBlocked, isEnabled and isBlockingAllowed are replaced by active. Application layouts referencing them must be adapted.
- Blocking states stored in the database are taken over automatically as the administrator's choice (blocked = inactive, unblocked = active).
- A customer component library replacing the React part FieldValue receives the optional props preformatted and action; the part list contains the part CopyButton.
- Weitere entfallene API: die Filter com.top_logic.util.sched.entry.filter.EnabledSchedulerEntryFilter und ManuallyStartedSchedulerEntryFilter, die Klassen BlockState und BlockStateRenderer (com.top_logic.util.sched.layout.block), TaskImpl.isBlockedByDefault() sowie an SchedulerEntry der Konstruktor SchedulerEntry(Task, boolean) und die Methoden setEnabled / isEnabled / setAttached / isAttached / createThread. Eigene Layouts und eigener Code, die sie verwenden, fragen stattdessen Scheduler.isActive(Task) ab bzw. entfernen die Verwendung.