Fix context lifecycle in scheduled actions

Remove ctx field from scheduledActs struct and create a fresh context
when actions execute via cron. This prevents "context canceled" errors
that occurred when stored contexts from API calls were used for delayed
execution. The context is now properly received from the caller in case
of "*asap" actions.
This commit is contained in:
ionutboangiu
2025-05-21 11:08:30 +03:00
committed by Dan Christian Bogos
parent 7fe60c2b8b
commit c3bf93f1b6
3 changed files with 7 additions and 7 deletions

View File

@@ -268,7 +268,7 @@ func (aS *ActionS) asapExecuteActions(ctx *context.Context, sActs *scheduledActs
utils.ActionS, sActs.tenant, sActs.apID, err))
return
}
if err = sActs.Execute(); err != nil { // cannot remove due to errors on execution
if err = sActs.Execute(ctx); err != nil { // cannot remove due to errors on execution
return
}
delete(ap.Targets[sActs.trgTyp], sActs.trgID)

View File

@@ -1051,7 +1051,6 @@ func TestACScheduledActions(t *testing.T) {
trgTyp: utils.MetaStats,
trgID: "ID_TEST",
schedule: utils.EmptyString,
ctx: context.Background(),
data: mapStorage,
},
}

View File

@@ -50,7 +50,6 @@ func newScheduledActs(ctx *context.Context, tenant, apID, trgTyp, trgID, schedul
trgTyp: trgTyp,
trgID: trgID,
schedule: schedule,
ctx: ctx,
data: data,
acts: acts,
cch: ltcache.NewTransCache(map[string]*ltcache.CacheConfig{}),
@@ -64,7 +63,6 @@ type scheduledActs struct {
trgTyp string
trgID string
schedule string
ctx *context.Context
data utils.MapStorage
acts []actioner
@@ -73,15 +71,18 @@ type scheduledActs struct {
// Execute is called when we want the ActionProfile to be executed
func (s *scheduledActs) ScheduledExecute() {
s.Execute()
// Create a fresh root context when cron triggers execution.
// TODO: decide whether a timeout should be configured.
ctx := context.Background()
s.Execute(ctx)
}
// Execute notifies possible errors on execution
func (s *scheduledActs) Execute() (err error) {
func (s *scheduledActs) Execute(ctx *context.Context) (err error) {
var partExec bool
for _, act := range s.acts {
//ctx, cancel := context.WithTimeout(s.ctx, act.cfg().TTL)
if err := act.execute(s.ctx, s.data, s.trgID); err != nil {
if err := act.execute(ctx, s.data, s.trgID); err != nil {
utils.Logger.Warning(fmt.Sprintf("executing action: <%s>, error: <%s>", act.id(), err))
partExec = true
}