package server import ( "fmt" "io/ioutil" "net" "os" "path/filepath" "reflect" "strconv" "git.loafle.net/commons_go/logging" "git.loafle.net/commons_go/server" oocu "git.loafle.net/overflow/overflow_commons_go/util" ) func NewServerHandler(pidPath string, serverName string, socketHandler SocketHandler, services []interface{}, servicesToStartAndStop []reflect.Type) ServerHandler { pidPathABS, err := filepath.Abs(pidPath) if nil != err { logging.Logger().Panicf("Container: pid file path[%s] is not valid %v", pidPath, err) } sh := &ServerHandlers{ pidPath: pidPath, pidPathABS: pidPathABS, services: services, servicesToStartAndStop: servicesToStartAndStop, } sh.Name = serverName sh.SocketHandler = socketHandler return sh } type ServerHandlers struct { server.ServerHandlers pidPath string pidPathABS string port int services []interface{} servicesToStartAndStop []reflect.Type } func (sh *ServerHandlers) Init(serverCTX server.ServerContext) error { if err := sh.ServerHandlers.Init(serverCTX); nil != err { return err } if err := oocu.ExecuteStarters(sh.services, sh.servicesToStartAndStop, false); nil != err { return err } return nil } func (sh *ServerHandlers) Listen(serverCTX server.ServerContext) (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: Cannot find availrable port") } func (sh *ServerHandlers) OnStart(serverCTX server.ServerContext) { sh.ServerHandlers.OnStart(serverCTX) if _, err := os.Stat(sh.pidPathABS); os.IsExist(err) { if err := os.Remove(sh.pidPathABS); nil != err { logging.Logger().Errorf("Container: Removing pid file has been failed [%v]", err) } } s := strconv.FormatInt(int64(sh.port), 10) ioutil.WriteFile(sh.pidPathABS, []byte(s), os.ModePerm) } func (sh *ServerHandlers) OnStop(serverCTX server.ServerContext) { if _, err := os.Stat(sh.pidPathABS); os.IsExist(err) { if err := os.Remove(sh.pidPathABS); nil != err { logging.Logger().Errorf("Container: Removing pid file has been failed [%v]", err) } } sh.ServerHandlers.OnStop(serverCTX) } func (sh *ServerHandlers) Destroy(serverCTX server.ServerContext) { if err := oocu.ExecuteStoppers(sh.services, sh.servicesToStartAndStop, true); nil != err { logging.Logger().Error(err) } sh.ServerHandlers.Destroy(serverCTX) } func (sh *ServerHandlers) Validate() { sh.ServerHandlers.Validate() if "" == sh.pidPath { logging.Logger().Panicf("Container: The path of pid file must be specified") } }