enhancement
major
minor
defect
critical
major
minor
major
#30090
Scheduler: A task that is due at startup is detached during shutdown while it is still running (NullPointerException in TaskImpl.getLog())
Problem
Since #30057 (commit f26eab48b1) the scheduler starts due tasks, e.g. those scheduled on-startup, in its first round instead of after the first polling interval. An application that is stopped right after its start (the test setup of TestMigrationRewrite starts and stops the application several times) now regularly has RefreshUsersTask running at the time of the shutdown.
Jenkins tl-ci-pr build 789 (PR !2089, unrelated to the scheduler), ScriptedTest(shard-1)#test.com.top_logic.test.app.rewrite.TestMigrationRewrite TestUI: "An error was logged during the test execution! 5 error(s) were logged":
Thread 'RefreshUsersTask' was destroyed by uncaught exception of type java.lang.NullPointerException. Message: Cannot invoke "com.top_logic.util.sched.task.log.TaskLog.getCurrentResult()" because the return value of "com.top_logic.util.sched.task.impl.TaskImpl.getLog()" is null MultiError: Failed to stop task 'RefreshUsersTask' after 20 attempts. Assuming the task does not want to be stopped. at com.top_logic.util.sched.task.impl.TaskImpl.signalStop(TaskImpl.java:835) at com.top_logic.basic.sched.BatchImpl.signalShutdown(BatchImpl.java:73) at com.top_logic.util.sched.Scheduler.signalShutdown(Scheduler.java:692) at com.top_logic.util.sched.Scheduler.shutDownThreadWithThreadContext(Scheduler.java:2180) ... Caused by: java.lang.NullPointerException: Cannot invoke "TaskLog.getState()" because the return value of "TaskImpl.getLog()" is null at com.top_logic.util.sched.task.impl.TaskImpl.trySignalStopClusterGlobal(TaskImpl.java:886)
Timeline from the log: task started 23:27:36,265; Scheduler.shutDown() begins 23:27:36,276 and returns exactly 5 s later (shutdown-join-time), the dispatch thread still being alive ("Scheduler still running"). shutDown() then unregisters all tasks, which detaches them and sets their log to null, while the dispatch thread is still in its shutdown phase (it waits up to time-to-kill) and the task thread is still running. Both then dereference the missing log.
Analysis and fix follow in the comments.