// Package task contains the process-wide task method contract. It is an // infrastructure registry, not a system business package, so any module can // contribute an in-process scheduled task. package task import ( "context" "encoding/json" "sort" "sync" ) type MethodFunc func(context.Context, json.RawMessage) error type Method struct { Name, Description string Run MethodFunc } type Registry struct { mu sync.RWMutex methods map[string]Method } func NewRegistry() *Registry { return &Registry{methods: make(map[string]Method)} } func (r *Registry) Register(method Method) { if r == nil || method.Name == "" || method.Run == nil { return } r.mu.Lock() defer r.mu.Unlock() if r.methods == nil { r.methods = make(map[string]Method) } r.methods[method.Name] = method } func (r *Registry) RegisterAll(methods []Method) { for _, method := range methods { r.Register(method) } } func (r *Registry) Lookup(name string) (MethodFunc, bool) { if r == nil { return nil, false } r.mu.RLock() defer r.mu.RUnlock() method, ok := r.methods[name] if !ok { return nil, false } return method.Run, true } func (r *Registry) List() []Method { if r == nil { return nil } r.mu.RLock() defer r.mu.RUnlock() methods := make([]Method, 0, len(r.methods)) for _, method := range r.methods { methods = append(methods, method) } sort.Slice(methods, func(i, j int) bool { return methods[i].Name < methods[j].Name }) return methods }