diff --git a/server.go b/server.go index a229bfe..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 { @@ -90,8 +97,6 @@ func handleServer(s *server) { if stopping.Load() == nil { logging.Logger().Error(fmt.Sprintf("Server: Cannot accept new connection: [%s]", err)) } - } else { - conn, err = s.sh.OnAccept(conn) } close(acceptChan) }() @@ -124,9 +129,17 @@ func handleServer(s *server) { func handleConnection(s *server, conn net.Conn) { defer s.stopWg.Done() + 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{}) handleDoneChan := make(chan struct{}) + go s.sh.Handle(conn, clientStopChan, handleDoneChan) select { diff --git a/server_handler.go b/server_handler.go index cd9f06a..de433c8 100644 --- a/server_handler.go +++ b/server_handler.go @@ -5,13 +5,44 @@ import ( ) type ServerHandler interface { - Listen() (net.Listener, error) - OnAccept(conn net.Conn) (net.Conn, error) + // Init invoked before the server is started + // If you override ths method, must call + // + // func (sh *ServerHandler) Init() error { + // if err := sh.ServerHandler.Init(); nil != err { + // return err + // } + // ... + // return nil + // } + Init() error + Listen() (net.Listener, error) + // OnStart invoked when server is started + // If you override ths method, must call + // + // func (sh *ServerHandler) OnStart() error { + // sh.ServerHandler.OnStart() + // ... + // return nil + // } OnStart() - OnStop() + + OnConnect(conn net.Conn) (net.Conn, error) Handle(conn net.Conn, stopChan <-chan struct{}, doneChan chan<- struct{}) + OnError(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() + + GetName() string + Validate() } diff --git a/server_handlers.go b/server_handlers.go index 6a2e46c..2d3788c 100644 --- a/server_handlers.go +++ b/server_handlers.go @@ -2,26 +2,36 @@ package server import ( "errors" + "fmt" "log" "net" + + "git.loafle.net/commons_go/logging" ) type ServerHandlers struct { + // Server name for sending in response headers. + // + // Default server name is used if left blank. + Name string } -func (sh *ServerHandlers) OnStart() { - // no op -} +func (sh *ServerHandlers) Init() error { -func (sh *ServerHandlers) OnStop() { - // no op + return nil } func (sh *ServerHandlers) Listen() (net.Listener, error) { return nil, errors.New("Server: Handler method[Listen] of Server is not implement") } -func (sh *ServerHandlers) OnAccept(conn net.Conn) (net.Conn, error) { +// OnStart invoked when server is stated +// If you override ths method, must call +func (sh *ServerHandlers) OnStart() { + // no op +} + +func (sh *ServerHandlers) OnConnect(conn net.Conn) (net.Conn, error) { return conn, nil } @@ -29,6 +39,20 @@ func (sh *ServerHandlers) Handle(conn net.Conn, stopChan <-chan struct{}, doneCh log.Printf("Server.Handle") } +func (sh *ServerHandlers) OnError(status int, reason error) { + logging.Logger().Error(fmt.Sprintf("Server: error status: %d, reason: %v", status, reason)) +} + +// OnStop invoked when server is stopped +// If you override ths method, must call +func (sh *ServerHandlers) OnStop() { + // no op +} + +func (sh *ServerHandlers) GetName() string { + return sh.Name +} + func (sh *ServerHandlers) Validate() { }