From 52bc3526070215a1f7a7aa352b84d630c9f3923f Mon Sep 17 00:00:00 2001 From: Artem Kuleshov Date: Fri, 21 Aug 2026 17:37:16 +0300 Subject: [PATCH 1/2] [addon-operator] create module hook queues regardless of DoModuleStartup Signed-off-by: Artem Kuleshov --- pkg/task/tasks/module-run/task.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/pkg/task/tasks/module-run/task.go b/pkg/task/tasks/module-run/task.go index 78a3aafd..730b8090 100644 --- a/pkg/task/tasks/module-run/task.go +++ b/pkg/task/tasks/module-run/task.go @@ -188,15 +188,17 @@ 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 { + // Start queues for module hooks. Every phase below queues tasks into them, + // and the phases are reached with or without module startup, so the queues + // must not depend on DoModuleStartup (the call is idempotent). + s.CreateAndStartQueuesForModuleHooks(baseModule.GetName()) + if hm.DoModuleStartup { s.logger.Debug("ModuleRun phase", slog.String(pkg.LogKeyPhase, string(baseModule.GetPhase()))) treg := trace.StartRegion(context.Background(), "ModuleRun-OnStartup") - // 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 { @@ -237,10 +239,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. From f59e4167159b90c621c50cb87512b2796c706409 Mon Sep 17 00:00:00 2001 From: Artem Kuleshov Date: Fri, 21 Aug 2026 17:58:58 +0300 Subject: [PATCH 2/2] [addon-operator] run module startup phase regardless of DoModuleStartup Signed-off-by: Artem Kuleshov --- pkg/task/tasks/module-run/task.go | 27 +++++++++++---------------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/pkg/task/tasks/module-run/task.go b/pkg/task/tasks/module-run/task.go index 730b8090..56cd9af5 100644 --- a/pkg/task/tasks/module-run/task.go +++ b/pkg/task/tasks/module-run/task.go @@ -188,28 +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 { - // Start queues for module hooks. Every phase below queues tasks into them, - // and the phases are reached with or without module startup, so the queues - // must not depend on DoModuleStartup (the call is idempotent). - s.CreateAndStartQueuesForModuleHooks(baseModule.GetName()) - - 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") - // Run onStartup hooks. - moduleRunErr = s.moduleManager.RunModuleHooks(ctx, baseModule, htypes.OnStartup, s.shellTask.GetLogLabels()) - if moduleRunErr == nil { - s.moduleManager.SetModulePhaseAndNotify(baseModule, modules.OnStartupDone) - } + // Start queues for module hooks. + s.CreateAndStartQueuesForModuleHooks(baseModule.GetName()) - 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