优化结构
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
package task
|
||||
|
||||
import "github.com/google/wire"
|
||||
|
||||
var ProviderSet = wire.NewSet(NewRegistry)
|
||||
@@ -0,0 +1,88 @@
|
||||
// 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
|
||||
}
|
||||
|
||||
// Contributor registers task methods whose handlers need constructed runtime
|
||||
// dependencies. Modules expose a contributor and the application composition
|
||||
// root activates it; the task runtime never imports business modules.
|
||||
type Contributor interface {
|
||||
RegisterTasks(*Registry)
|
||||
}
|
||||
|
||||
type Registry struct {
|
||||
mu sync.RWMutex
|
||||
methods map[string]Method
|
||||
}
|
||||
|
||||
func NewRegistry() *Registry { return &Registry{methods: make(map[string]Method)} }
|
||||
|
||||
func Apply(registry *Registry, contributors ...Contributor) {
|
||||
if registry == nil {
|
||||
return
|
||||
}
|
||||
for _, contributor := range contributors {
|
||||
if contributor != nil {
|
||||
contributor.RegisterTasks(registry)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package task
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestRegistryIsComposableAndIdempotent(t *testing.T) {
|
||||
registry := NewRegistry()
|
||||
registry.RegisterAll([]Method{{Name: "orders.sync", Run: func(context.Context, json.RawMessage) error { return nil }}, {Name: "system.cleanup", Run: func(context.Context, json.RawMessage) error { return nil }}})
|
||||
registry.Register(Method{Name: "orders.sync", Description: "updated", Run: func(context.Context, json.RawMessage) error { return nil }})
|
||||
methods := registry.List()
|
||||
if len(methods) != 2 || methods[0].Name != "orders.sync" || methods[0].Description != "updated" {
|
||||
t.Fatalf("unexpected methods: %#v", methods)
|
||||
}
|
||||
}
|
||||
|
||||
type testContributor struct{ name string }
|
||||
|
||||
func (contributor testContributor) RegisterTasks(registry *Registry) {
|
||||
registry.Register(Method{Name: contributor.name, Run: func(context.Context, json.RawMessage) error { return nil }})
|
||||
}
|
||||
|
||||
func TestApplyCollectsModuleContributors(t *testing.T) {
|
||||
registry := NewRegistry()
|
||||
Apply(registry, testContributor{name: "system.cleanup"}, testContributor{name: "orders.expire"})
|
||||
methods := registry.List()
|
||||
if len(methods) != 2 || methods[0].Name != "orders.expire" || methods[1].Name != "system.cleanup" {
|
||||
t.Fatalf("unexpected contributed methods: %#v", methods)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user