container-go/server/server-handler.go
crusader f93dcf388a ing
2018-04-19 16:01:08 +09:00

120 lines
2.9 KiB
Go

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
}