113 lines
2.9 KiB
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()
|
|
}
|
|
}
|