diff --git a/server.go b/server.go index e2c4800..122dd53 100644 --- a/server.go +++ b/server.go @@ -10,12 +10,6 @@ import ( "git.loafle.net/commons_go/logging" ) -type Server interface { - Start() error - Stop() - Serve() error -} - func New(sh ServerHandler) Server { s := &server{ sh: sh, @@ -23,6 +17,12 @@ func New(sh ServerHandler) Server { return s } +type Server interface { + Start() error + Stop() + Serve() error +} + type server struct { sh ServerHandler @@ -48,6 +48,10 @@ func (s *server) Start() error { return err } + if err = s.sh.Init(); nil != err { + logging.Logger().Panic(fmt.Sprintf("Server: Initialization of server has been failed %v", err)) + } + s.stopChan = make(chan struct{}) s.sh.OnStart() @@ -65,7 +69,10 @@ func (s *server) Stop() { close(s.stopChan) s.stopWg.Wait() s.stopChan = nil + s.sh.OnStop() + + logging.Logger().Info(fmt.Sprintf("Server[%s] is stopped", s.sh.GetName())) } func (s *server) Serve() error { @@ -88,10 +95,8 @@ func handleServer(s *server) { go func() { if conn, err = s.listener.Accept(); err != nil { if stopping.Load() == nil { - logging.Logger.Error(fmt.Sprintf("Server: Cannot accept new connection: [%s]", err)) + logging.Logger().Error(fmt.Sprintf("Server: Cannot accept new connection: [%s]", err)) } - } else { - conn, err = s.sh.OnAccept(conn) } close(acceptChan) }() @@ -124,19 +129,27 @@ func handleServer(s *server) { func handleConnection(s *server, conn net.Conn) { defer s.stopWg.Done() - logging.Logger.Debug(fmt.Sprintf("Server: Client[%s] is connected.", conn.RemoteAddr())) + var err error + if conn, err = s.sh.OnConnect(conn); nil != err { + logging.Logger().Error(fmt.Sprintf("Server: connecting[%s] failed %v", conn.RemoteAddr(), err)) + return + } + + logging.Logger().Debug(fmt.Sprintf("Server: Client[%s] is connected.", conn.RemoteAddr())) + clientStopChan := make(chan struct{}) - handleDoneCnah := make(chan struct{}) - go s.sh.Handle(conn, clientStopChan, handleDoneCnah) + handleDoneChan := make(chan struct{}) + + go s.sh.Handle(conn, clientStopChan, handleDoneChan) select { case <-s.stopChan: close(clientStopChan) conn.Close() - <-handleDoneCnah - case <-handleDoneCnah: + <-handleDoneChan + case <-handleDoneChan: close(clientStopChan) conn.Close() - logging.Logger.Debug(fmt.Sprintf("Server: Client[%s] is disconnected.", conn.RemoteAddr())) + logging.Logger().Debug(fmt.Sprintf("Server: Client[%s] is disconnected.", conn.RemoteAddr())) } } diff --git a/server_handler.go b/server_handler.go index 3c37272..7df1395 100644 --- a/server_handler.go +++ b/server_handler.go @@ -12,9 +12,16 @@ type ServerHandler interface { OnError(serverCTX ServerContext, conn net.Conn, status int, reason error) + // OnStop invoked when server is stopped + // If you override ths method, must call + // + // func (sh *ServerHandler) OnStop() { + // ... + // sh.ServerHandler.OnStop() + // } OnStop(serverCTX ServerContext) - IsClientDisconnect(err error) bool + GetName() string Validate() } diff --git a/server_handlers.go b/server_handlers.go index 0bd260e..4b47c5c 100644 --- a/server_handlers.go +++ b/server_handlers.go @@ -2,16 +2,16 @@ package server import ( "errors" - "io" - "log" "net" ) -type ServerHandlers struct { +func NewServerHandler() ServerHandler { + sh := &ServerHandlers{} + return sh } func (sh *ServerHandlers) ServerContext() ServerContext { - + return newServerContext() } func (sh *ServerHandlers) Init(serverCTX ServerContext) error { @@ -26,32 +26,18 @@ func (sh *ServerHandlers) OnStart(serverCTX ServerContext) { // no op } -func (sh *ServerHandlers) OnAccept(conn net.Conn) (net.Conn, error) { - -} - -func (sh *ServerHandlers) Handle(serverCTX ServerContext, conn net.Conn, stopChan <-chan struct{}, doneChan chan<- struct{}) { - -} - func (sh *ServerHandlers) OnError(serverCTX ServerContext, conn net.Conn, status int, reason error) { } +// OnStop invoked when server is stopped +// If you override ths method, must call func (sh *ServerHandlers) OnStop(serverCTX ServerContext) { // no op } -func (sh *ServerHandlers) OnAccept(conn net.Conn) (net.Conn, error) { - return conn, nil -} - -func (sh *ServerHandlers) Handle(conn net.Conn, stopChan <-chan struct{}, doneChan chan<- struct{}) { - log.Printf("Server.Handle") -} - -func (sh *ServerHandlers) IsClientDisconnect(err error) bool { - return err == io.ErrUnexpectedEOF || err == io.EOF +func (sh *ServerHandlers) GetName() string { + return sh.Name } func (sh *ServerHandlers) Validate() { diff --git a/util.go b/util.go new file mode 100644 index 0000000..ecb2790 --- /dev/null +++ b/util.go @@ -0,0 +1,7 @@ +package server + +import "io" + +func IsClientDisconnect(err error) bool { + return err == io.ErrUnexpectedEOF || err == io.EOF +}