go/task.go

62 lines
1.7 KiB
Go
Raw Normal View History

// SPDX-License-Identifier: EUPL-1.2
// Background action dispatch for the Core framework.
// PerformAsync runs a named Action in a background goroutine with
// panic recovery and progress broadcasting.
package core
import "context"
// PerformAsync dispatches a named action in a background goroutine.
// Broadcasts ActionTaskStarted, ActionTaskProgress, and ActionTaskCompleted
// as IPC messages so other services can track progress.
//
// r := c.PerformAsync("agentic.dispatch", opts)
// taskID := r.Value.(string)
func (c *Core) PerformAsync(action string, opts Options) Result {
if c.shutdown.Load() {
return Result{}
}
taskID := ID()
c.ACTION(ActionTaskStarted{TaskIdentifier: taskID, Action: action, Options: opts})
c.waitGroup.Go(func() {
defer func() {
if rec := recover(); rec != nil {
c.ACTION(ActionTaskCompleted{
TaskIdentifier: taskID,
Action: action,
Result: Result{E("core.PerformAsync", Sprint("panic: ", rec), nil), false},
})
}
}()
r := c.Action(action).Run(context.Background(), opts)
c.ACTION(ActionTaskCompleted{
TaskIdentifier: taskID,
Action: action,
Result: r,
})
})
return Result{taskID, true}
}
// Progress broadcasts a progress update for a background task.
//
// c.Progress(taskID, 0.5, "halfway done", "agentic.dispatch")
func (c *Core) Progress(taskID string, progress float64, message string, action string) {
c.ACTION(ActionTaskProgress{
TaskIdentifier: taskID,
Action: action,
Progress: progress,
Message: message,
})
}
// Registration methods (RegisterAction, RegisterActions)
feat: implement RFC plans 1-5 — Registry[T], Action/Task, Process, primitives Plans 1-5 complete for core/go scope. 456 tests, 84.4% coverage, 100% AX-7 naming. Critical bugs (Plan 1): - P4-3+P7-3: ACTION broadcast calls all handlers with panic recovery - P7-2+P7-4: RunE() with defer ServiceShutdown, Run() delegates - P3-1: Startable/Stoppable return Result (breaking, clean) - P9-1: Zero os/exec — App.Find() rewritten with os.Stat+PATH - I3: Embed() removed, I15: New() comment fixed - I9: CommandLifecycle removed → Command.Managed field Registry[T] (Plan 2): - Universal thread-safe named collection with 3 lock modes - All 5 registries migrated: services, commands, drive, data, lock - Insertion order preserved (fixes P4-1) - c.RegistryOf("name") cross-cutting accessor Action/Task system (Plan 3): - Action type with Run()/Exists(), ActionHandler signature - c.Action("name") dual-purpose accessor (register/invoke) - TaskDef with Steps — sequential chain, async dispatch, previous-input piping - Panic recovery on all Action execution - broadcast() internal, ACTION() sugar Process primitive (Plan 4): - c.Process() returns Action sugar — Run/RunIn/RunWithEnv/Start/Kill/Exists - No deps added — delegates to c.Action("process.*") - Permission-by-registration: no handler = no capability Missing primitives (Plan 5): - core.ID() — atomic counter + crypto/rand suffix - ValidateName() / SanitisePath() — reusable validation - Fs.WriteAtomic() — write-to-temp-then-rename - Fs.NewUnrestricted() / Fs.Root() — legitimate sandbox bypass - AX-7: 456/456 tests renamed to TestFile_Function_{Good,Bad,Ugly} Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-25 15:18:25 +00:00
// are in ipc.go — registration is IPC's responsibility.