diff --git a/pkg/task/tasks/module-run/task.go b/pkg/task/tasks/module-run/task.go index 78a3aafd..56cd9af5 100644 --- a/pkg/task/tasks/module-run/task.go +++ b/pkg/task/tasks/module-run/task.go @@ -188,26 +188,23 @@ func (s *Task) Handle(ctx context.Context) (res queue.TaskResult) { //nolint:non // Register module hooks on every enable. moduleRunErr = s.moduleManager.RegisterModuleHooks(baseModule, taskLogLabels) if moduleRunErr == nil { - if hm.DoModuleStartup { - s.logger.Debug("ModuleRun phase", - slog.String(pkg.LogKeyPhase, string(baseModule.GetPhase()))) + s.logger.Debug("ModuleRun phase", + slog.String(pkg.LogKeyPhase, string(baseModule.GetPhase()))) - treg := trace.StartRegion(context.Background(), "ModuleRun-OnStartup") + treg := trace.StartRegion(context.Background(), "ModuleRun-OnStartup") - // Start queues for module hooks. - s.CreateAndStartQueuesForModuleHooks(baseModule.GetName()) + // Start queues for module hooks. + s.CreateAndStartQueuesForModuleHooks(baseModule.GetName()) - // Run onStartup hooks. - moduleRunErr = s.moduleManager.RunModuleHooks(ctx, baseModule, htypes.OnStartup, s.shellTask.GetLogLabels()) - if moduleRunErr == nil { - s.moduleManager.SetModulePhaseAndNotify(baseModule, modules.OnStartupDone) - } - - treg.End() - } else { + // Run onStartup hooks. The Startup phase already means they have not run, so this + // must not depend on DoModuleStartup, which each ModuleRun producer computes itself. + moduleRunErr = s.moduleManager.RunModuleHooks(ctx, baseModule, htypes.OnStartup, s.shellTask.GetLogLabels()) + if moduleRunErr == nil { s.moduleManager.SetModulePhaseAndNotify(baseModule, modules.OnStartupDone) } + treg.End() + res.Status = queue.Repeat return res @@ -237,10 +234,8 @@ func (s *Task) Handle(ctx context.Context) (res queue.TaskResult) { //nolint:non s.logger.Debug("ModuleRun phase", slog.String(pkg.LogKeyPhase, string(baseModule.GetPhase()))) - // Hook queues are normally created in the Startup phase, but only when - // DoModuleStartup is set, and a converge restart can displace that task. - // A missing queue would make every AddLastTaskToQueue below fail - // deterministically, so ensure the queues exist (the call is idempotent). + // Queues are created in the Startup phase; ensure them again so that a hook + // registered later cannot lose its Synchronization task. Idempotent. s.CreateAndStartQueuesForModuleHooks(hm.ModuleName) // ModuleHookRun.Synchronization tasks for bindings with the "main" queue.