vRp.CD2g_test/server/multiple.go

113 lines
2.9 KiB
Go

package server
import (
"github.com/kercylan98/minotaur/utils/log"
"go.uber.org/zap"
"os"
"os/signal"
"sync"
"syscall"
)
func NewMultipleServer(serverHandle ...func() (addr string, srv *Server)) *MultipleServer {
ms := &MultipleServer{
servers: make([]*Server, len(serverHandle), len(serverHandle)),
addresses: make([]string, len(serverHandle), len(serverHandle)),
}
for i := 0; i < len(serverHandle); i++ {
ms.addresses[i], ms.servers[i] = serverHandle[i]()
}
return ms
}
type MultipleServer struct {
servers []*Server
addresses []string
exitEventHandles []func()
}
func (slf *MultipleServer) Run() {
var exceptionChannel = make(chan error, 1)
var runtimeExceptionChannel = make(chan error, 1)
defer func() {
close(exceptionChannel)
close(runtimeExceptionChannel)
}()
var running = make([]*Server, 0, len(slf.servers))
var wait sync.WaitGroup
for i := 0; i < len(slf.servers); i++ {
wait.Add(1)
go func(address string, server *Server) {
var startFinish bool
server.startFinishEventHandles = append(server.startFinishEventHandles, func(srv *Server) {
if !startFinish {
startFinish = true
wait.Done()
}
})
server.multiple = slf
server.multipleRuntimeErrorChan = runtimeExceptionChannel
if err := server.Run(address); err != nil {
exceptionChannel <- err
} else {
running = append(running, server)
}
if !startFinish {
startFinish = true
wait.Done()
}
}(slf.addresses[i], slf.servers[i])
}
wait.Wait()
log.Info("Server", zap.String(serverMultipleMark, "===================================================================="))
for _, server := range slf.servers {
log.Info("Server", zap.String(serverMultipleMark, "RunningInfo"),
zap.Any("network", server.network),
zap.String("listen", server.addr),
)
}
log.Info("Server", zap.String(serverMultipleMark, "===================================================================="))
systemSignal := make(chan os.Signal, 1)
signal.Notify(systemSignal, syscall.SIGHUP, syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT)
select {
case err := <-exceptionChannel:
for len(slf.servers) > 0 {
server := slf.servers[0]
server.shutdown(err)
slf.servers = slf.servers[1:]
}
break
case <-runtimeExceptionChannel:
for len(slf.servers) > 0 {
server := slf.servers[0]
server.multipleRuntimeErrorChan = nil
server.shutdown(nil)
slf.servers = slf.servers[1:]
}
break
case <-systemSignal:
for len(slf.servers) > 0 {
server := slf.servers[0]
server.multipleRuntimeErrorChan = nil
server.shutdown(nil)
slf.servers = slf.servers[1:]
}
break
}
slf.OnExitEvent()
}
// RegExitEvent 注册退出事件
func (slf *MultipleServer) RegExitEvent(handle func()) {
slf.exitEventHandles = append(slf.exitEventHandles, handle)
}
func (slf *MultipleServer) OnExitEvent() {
for _, handle := range slf.exitEventHandles {
handle()
}
}