package service import ( "context" "errors" "outsourcing/pkg/logx" "sort" ) // SubInitializer 提供 source/*/init() 使用的接口,每个 initializer 完成一个初始化过程 type SubInitializer interface { InitializerName() string // 不一定代表单独一个表,所以改成了更宽泛的语义 InitializeData(ctx context.Context) (next context.Context, err error) DataInserted(ctx context.Context) bool } // orderedInitializer 组合一个顺序字段,以供排序 type orderedInitializer struct { order int SubInitializer } // initSlice 供 initializerList 排序依赖时使用 type initSlice []*orderedInitializer func (a initSlice) Len() int { return len(a) } func (a initSlice) Less(i, j int) bool { return a[i].order < a[j].order } func (a initSlice) Swap(i, j int) { a[i], a[j] = a[j], a[i] } var ( initializerList initSlice // 初始化列表 initializerMap map[string]*orderedInitializer // 初始化map ) // RegisterInit 注册要执行的初始化过程,会在 InitDB() 时调用 func RegisterInit(order int, subInit SubInitializer) { if initializerList == nil { initializerList = initSlice{} } if initializerMap == nil { initializerMap = map[string]*orderedInitializer{} } subInitName := subInit.InitializerName() if _, existed := initializerMap[subInitName]; existed { logx.Errorf("Name conflict on %s", subInitName) return } orderedSubInit := orderedInitializer{order, subInit} initializerList = append(initializerList, &orderedSubInit) initializerMap[subInitName] = &orderedSubInit } type InitDBService struct{} // InitDB 初始化 func (initDBService *InitDBService) InitDB() (err error) { if len(initializerList) == 0 { return errors.New("无可用初始化过程,请检查初始化是否已执行完成") } sort.Sort(&initializerList) // 保证有依赖的 initializer 排在后面执行 initHandler := NewMysqlInitHandler() if err = initHandler.InitData(context.TODO(), initializerList); err != nil { logx.Errorf("InitDB InitData err:%v", err) return err } initializerList = initSlice{} initializerMap = map[string]*orderedInitializer{} return nil }