package server import ( "fmt" "io/ioutil" "net" "os" "reflect" "strconv" logging "git.loafle.net/commons/logging-go" "git.loafle.net/commons/server-go" cssn "git.loafle.net/commons/server-go/socket/net" occi "git.loafle.net/overflow/commons-go/core/interfaces" ) type ServerHandler interface { cssn.ServerHandler } type ServerHandlers struct { cssn.ServerHandlers PIDFilePath string Services []interface{} OrderedServices []reflect.Type port int } func (sh *ServerHandlers) Init(serverCtx server.ServerCtx) error { if err := sh.ServerHandlers.Init(serverCtx); nil != err { return err } if err := occi.ExecServices(sh.Services, occi.ServiceMethodInit, sh.OrderedServices, false); nil != err { return err } return nil } func (sh *ServerHandlers) OnStart(serverCtx server.ServerCtx) error { if err := sh.ServerHandlers.OnStart(serverCtx); nil != err { return err } if err := occi.ExecServices(sh.Services, occi.ServiceMethodStart, sh.OrderedServices, false); nil != err { return err } if _, err := os.Stat(sh.PIDFilePath); os.IsExist(err) { if err := os.Remove(sh.PIDFilePath); nil != err { logging.Logger().Errorf("Container[%s]: Removing pid file has been failed [%v]", sh.Name, err) } } s := strconv.FormatInt(int64(sh.port), 10) if err := ioutil.WriteFile(sh.PIDFilePath, []byte(s), os.ModePerm); nil != err { return err } return nil } func (sh *ServerHandlers) OnStop(serverCtx server.ServerCtx) { if err := occi.ExecServices(sh.Services, occi.ServiceMethodStop, sh.OrderedServices, true); nil != err { logging.Logger().Errorf("Container[%s]: Service stop err %v", sh.Name, err) } if _, err := os.Stat(sh.PIDFilePath); os.IsExist(err) { if err := os.Remove(sh.PIDFilePath); nil != err { logging.Logger().Errorf("Container: Removing pid file has been failed [%v]", err) } } sh.ServerHandlers.OnStop(serverCtx) } func (sh *ServerHandlers) Destroy(serverCtx server.ServerCtx) { if err := occi.ExecServices(sh.Services, occi.ServiceMethodDestroy, sh.OrderedServices, true); nil != err { logging.Logger().Errorf("Container[%s]: Service destroy err %v", sh.Name, err) } sh.ServerHandlers.Destroy(serverCtx) } func (sh *ServerHandlers) Listener(serverCtx server.ServerCtx) (net.Listener, error) { for i := 60000; i < 61000; i++ { addr := fmt.Sprintf("localhost:%d", i) l, err := net.Listen("tcp", addr) if nil == err { sh.port = i return l, nil } } return nil, fmt.Errorf("Container[%s]: Cannot find availrable port", sh.Name) } func (sh *ServerHandlers) Validate() error { if err := sh.ServerHandlers.Validate(); nil != err { return err } if "" == sh.PIDFilePath { return fmt.Errorf("Container[%s]: The path of pid file must be specified", sh.Name) } if nil == sh.Services { return fmt.Errorf("Container[%s]: Services must be specified", sh.Name) } if nil == sh.OrderedServices { return fmt.Errorf("Container[%s]: OrderedServices must be specified", sh.Name) } return nil }