kra-oa/internal/biz/task_registry.go

67 lines
1.8 KiB
Go

package biz
import (
"context"
"encoding/json"
"sort"
"sync"
)
// TaskMethodFunc is the execution contract for a registered in-process task.
// Implementations are responsible for decoding params and honoring ctx cancellation.
type TaskMethodFunc func(ctx context.Context, params json.RawMessage) error
type TaskMethod struct {
Name string
Description string
}
type taskMethodEntry struct {
meta TaskMethod
fn TaskMethodFunc
}
var taskMethodRegistry = struct {
sync.RWMutex
methods map[string]taskMethodEntry
}{methods: make(map[string]taskMethodEntry)}
// RegisterTaskMethod registers an in-process task. Re-registering the same name
// replaces the previous implementation so startup registration remains idempotent.
func RegisterTaskMethod(name, description string, fn TaskMethodFunc) {
taskMethodRegistry.Lock()
defer taskMethodRegistry.Unlock()
taskMethodRegistry.methods[name] = taskMethodEntry{
meta: TaskMethod{Name: name, Description: description},
fn: fn,
}
}
// TaskMethodByName returns the registered function for name.
func TaskMethodByName(name string) (TaskMethodFunc, bool) {
taskMethodRegistry.RLock()
defer taskMethodRegistry.RUnlock()
method, ok := taskMethodRegistry.methods[name]
if !ok {
return nil, false
}
return method.fn, true
}
// RegisteredTaskMethods returns task metadata in a stable name order.
func RegisteredTaskMethods() []TaskMethod {
taskMethodRegistry.RLock()
defer taskMethodRegistry.RUnlock()
methods := make([]TaskMethod, 0, len(taskMethodRegistry.methods))
for _, method := range taskMethodRegistry.methods {
methods = append(methods, method.meta)
}
sort.Slice(methods, func(i, j int) bool { return methods[i].Name < methods[j].Name })
return methods
}
func registeredTaskMethod(name string) bool {
_, ok := TaskMethodByName(name)
return ok
}