samba/pkg/task/manager.go

83 lines
1.2 KiB
Go
Raw Permalink Normal View History

2025-06-04 09:51:39 +08:00
package task
import (
"reflect"
"samba/pkg/service"
)
type Manager struct {
svr service.IService
tasks map[string]*Task
enable bool
}
type optional interface{ Apply(*Task) }
func NewManager(svr service.IService) *Manager {
return &Manager{
svr: svr,
tasks: make(map[string]*Task),
}
}
func (m *Manager) AddTask(ts ...Tasker) {
for _, t := range ts {
tk := m.NewTask(t.Name(), t.Do)
callApply(t, tk, 1)
t.Init(tk)
}
}
func (m *Manager) NewTask(name string, do task) *Task {
t := &Task{
name: name,
do: do,
svr: m.svr,
}
m.tasks[name] = t
return t
}
func (m *Manager) Submit() {
if m.enable {
return
}
for _, t := range m.tasks {
t.submit()
}
m.enable = true
}
func callApply(v any, t *Task, step int) {
val := reflect.ValueOf(v)
if val.Kind() == reflect.Ptr {
val = val.Elem()
}
if step > 1 {
if opt, ok := v.(optional); ok {
opt.Apply(t)
return
}
}
if val.Kind() != reflect.Struct {
return
}
for i := 0; i < val.NumField(); i++ {
field := val.Field(i)
if field.Kind() == reflect.Ptr && field.IsNil() {
newField := reflect.New(field.Type().Elem())
field.Set(newField)
}
if field.IsValid() && field.CanInterface() {
callApply(field.Interface(), t, step+1)
}
}
}