package interfaces import ( "fmt" "reflect" ) type Service interface { Init() error Start() error Stop() error Destroy() error } type ServiceMethodType int const ( Init ServiceMethodType = iota Start Stop Destroy ) var ( serviceMethodTypeID = map[ServiceMethodType]string{ Init: "Init", Start: "Start", Stop: "Stop", Destroy: "Destroy", } ) func (t ServiceMethodType) String() string { return serviceMethodTypeID[t] } func ExecServices(services []interface{}, method ServiceMethodType, orderedTypes []reflect.Type, reverse bool) error { if nil == services || 0 == len(services) { return nil } if nil == orderedTypes || 0 == len(orderedTypes) { return nil } tlen := len(orderedTypes) var _services []interface{} if reverse { for indexI := tlen - 1; indexI >= 0; indexI-- { t := orderedTypes[indexI] i := findServicesByType(services, t) if nil == i { return fmt.Errorf("service[%s] is not exist", t.Name()) } _services = append(_services, i) } } else { for indexI := 0; indexI < tlen; indexI++ { t := orderedTypes[indexI] i := findServicesByType(services, t) if nil == i { return fmt.Errorf("service[%s] is not exist", t.Name()) } _services = append(_services, i) } } if 0 == len(_services) { return nil } for indexI := 0; indexI < len(_services); indexI++ { i := _services[indexI] iv := reflect.ValueOf(i) m := iv.MethodByName(method.String()) rvs := m.Call([]reflect.Value{iv}) if nil != rvs && 1 == len(rvs) && nil != rvs[0].Interface() { return rvs[0].Interface().(error) } } return nil } func findServicesByType(services []interface{}, t reflect.Type) interface{} { for _, i := range services { if reflect.TypeOf(i) == t { return i } } return nil }