github.com/AntonOrnatskyi/goproxy@v0.0.0-20190205095733-4526a9fa18b4/services/service.go (about) 1 package services 2 3 import ( 4 "fmt" 5 logger "log" 6 "runtime/debug" 7 "sync" 8 ) 9 10 type Service interface { 11 Start(args interface{}, log *logger.Logger) (err error) 12 Clean() 13 } 14 type ServiceItem struct { 15 S Service 16 Args interface{} 17 Name string 18 Log *logger.Logger 19 } 20 21 var servicesMap = sync.Map{} 22 23 func Regist(name string, s Service, args interface{}, log *logger.Logger) { 24 Stop(name) 25 servicesMap.Store(name, &ServiceItem{ 26 S: s, 27 Args: args, 28 Name: name, 29 Log: log, 30 }) 31 } 32 func GetService(name string) *ServiceItem { 33 if s, ok := servicesMap.Load(name); ok && s.(*ServiceItem).S != nil { 34 return s.(*ServiceItem) 35 } 36 return nil 37 38 } 39 func Stop(name string) { 40 if s, ok := servicesMap.Load(name); ok && s.(*ServiceItem).S != nil { 41 s.(*ServiceItem).S.Clean() 42 *s.(*ServiceItem) = ServiceItem{} 43 s = nil 44 servicesMap.Store(name, nil) 45 servicesMap.Delete(name) 46 } 47 } 48 func Run(name string, args interface{}) (service *ServiceItem, err error) { 49 _service, ok := servicesMap.Load(name) 50 if ok { 51 defer func() { 52 e := recover() 53 if e != nil { 54 err = fmt.Errorf("%s servcie crashed, ERR: %s\ntrace:%s", name, e, string(debug.Stack())) 55 } 56 }() 57 service = _service.(*ServiceItem) 58 if args != nil { 59 err = service.S.Start(args, service.Log) 60 } else { 61 err = service.S.Start(service.Args, service.Log) 62 } 63 if err != nil { 64 err = fmt.Errorf("%s servcie fail, ERR: %s", name, err) 65 } 66 } else { 67 err = fmt.Errorf("service %s not found", name) 68 } 69 return 70 }