支持注册消息错误和慢执行事件
This commit is contained in:
parent
abe9a7b57c
commit
ce71a956e5
|
@ -5,6 +5,7 @@ import (
|
||||||
"github.com/kercylan98/minotaur/utils/runtimes"
|
"github.com/kercylan98/minotaur/utils/runtimes"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
type StartBeforeEventHandle func(srv *Server)
|
type StartBeforeEventHandle func(srv *Server)
|
||||||
|
@ -14,6 +15,8 @@ type ConnectionReceiveWebsocketPacketEventHandle func(srv *Server, conn *Conn, p
|
||||||
type ConnectionOpenedEventHandle func(srv *Server, conn *Conn)
|
type ConnectionOpenedEventHandle func(srv *Server, conn *Conn)
|
||||||
type ConnectionClosedEventHandle func(srv *Server, conn *Conn)
|
type ConnectionClosedEventHandle func(srv *Server, conn *Conn)
|
||||||
type ReceiveCrossPacketEventHandle func(srv *Server, senderServerId int64, packet []byte)
|
type ReceiveCrossPacketEventHandle func(srv *Server, senderServerId int64, packet []byte)
|
||||||
|
type MessageErrorEventHandle func(srv *Server, message *Message, err error)
|
||||||
|
type MessageLowExecEventHandle func(srv *Server, message *Message, cost time.Duration)
|
||||||
|
|
||||||
type event struct {
|
type event struct {
|
||||||
*Server
|
*Server
|
||||||
|
@ -24,6 +27,8 @@ type event struct {
|
||||||
connectionOpenedEventHandles []ConnectionOpenedEventHandle
|
connectionOpenedEventHandles []ConnectionOpenedEventHandle
|
||||||
connectionClosedEventHandles []ConnectionClosedEventHandle
|
connectionClosedEventHandles []ConnectionClosedEventHandle
|
||||||
receiveCrossPacketEventHandles []ReceiveCrossPacketEventHandle
|
receiveCrossPacketEventHandles []ReceiveCrossPacketEventHandle
|
||||||
|
messageErrorEventHandles []MessageErrorEventHandle
|
||||||
|
messageLowExecEventHandles []MessageLowExecEventHandle
|
||||||
}
|
}
|
||||||
|
|
||||||
// RegStartBeforeEvent 在服务器初始化完成启动前立刻执行被注册的事件处理函数
|
// RegStartBeforeEvent 在服务器初始化完成启动前立刻执行被注册的事件处理函数
|
||||||
|
@ -128,6 +133,30 @@ func (slf *event) OnReceiveCrossPacketEvent(serverId int64, packet []byte) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RegMessageErrorEvent 在处理消息发生错误时将立即执行被注册的事件处理函数
|
||||||
|
func (slf *event) RegMessageErrorEvent(handle MessageErrorEventHandle) {
|
||||||
|
slf.messageErrorEventHandles = append(slf.messageErrorEventHandles, handle)
|
||||||
|
log.Info("Server", zap.String("RegEvent", runtimes.CurrentRunningFuncName()), zap.String("handle", reflect.TypeOf(handle).String()))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (slf *event) OnMessageErrorEvent(message *Message, err error) {
|
||||||
|
for _, handle := range slf.messageErrorEventHandles {
|
||||||
|
handle(slf.Server, message, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// RegMessageLowExecEvent 在处理消息缓慢时将立即执行被注册的事件处理函数
|
||||||
|
func (slf *event) RegMessageLowExecEvent(handle MessageLowExecEventHandle) {
|
||||||
|
slf.messageLowExecEventHandles = append(slf.messageLowExecEventHandles, handle)
|
||||||
|
log.Info("Server", zap.String("RegEvent", runtimes.CurrentRunningFuncName()), zap.String("handle", reflect.TypeOf(handle).String()))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (slf *event) OnMessageLowExecEvent(message *Message, cost time.Duration) {
|
||||||
|
for _, handle := range slf.messageLowExecEventHandles {
|
||||||
|
handle(slf.Server, message, cost)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (slf *event) check() {
|
func (slf *event) check() {
|
||||||
switch slf.network {
|
switch slf.network {
|
||||||
case NetworkHttp, NetworkGRPC:
|
case NetworkHttp, NetworkGRPC:
|
||||||
|
|
|
@ -50,7 +50,7 @@ func (slf MessageErrorAction) String() string {
|
||||||
return messageErrorActionNames[slf]
|
return messageErrorActionNames[slf]
|
||||||
}
|
}
|
||||||
|
|
||||||
type message struct {
|
type Message struct {
|
||||||
t MessageType
|
t MessageType
|
||||||
attrs []any
|
attrs []any
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,9 +66,9 @@ type Server struct {
|
||||||
closeChannel chan struct{} // 关闭信号
|
closeChannel chan struct{} // 关闭信号
|
||||||
|
|
||||||
gServer *gNet // TCP或UDP模式下的服务器
|
gServer *gNet // TCP或UDP模式下的服务器
|
||||||
messagePool *synchronization.Pool[*message] // 消息池
|
messagePool *synchronization.Pool[*Message] // 消息池
|
||||||
messagePoolSize int // 消息池大小
|
messagePoolSize int // 消息池大小
|
||||||
messageChannel map[int]chan *message // 消息管道
|
messageChannel map[int]chan *Message // 消息管道
|
||||||
initMessageChannel bool // 消息管道是否已经初始化
|
initMessageChannel bool // 消息管道是否已经初始化
|
||||||
multiple bool // 是否为多服务器模式下运行
|
multiple bool // 是否为多服务器模式下运行
|
||||||
prod bool // 是否为生产模式
|
prod bool // 是否为生产模式
|
||||||
|
@ -101,18 +101,18 @@ func (slf *Server) Run(addr string) error {
|
||||||
if slf.messagePoolSize <= 0 {
|
if slf.messagePoolSize <= 0 {
|
||||||
slf.messagePoolSize = 100
|
slf.messagePoolSize = 100
|
||||||
}
|
}
|
||||||
slf.messagePool = synchronization.NewPool[*message](slf.messagePoolSize,
|
slf.messagePool = synchronization.NewPool[*Message](slf.messagePoolSize,
|
||||||
func() *message {
|
func() *Message {
|
||||||
return &message{}
|
return &Message{}
|
||||||
},
|
},
|
||||||
func(data *message) {
|
func(data *Message) {
|
||||||
data.t = 0
|
data.t = 0
|
||||||
data.attrs = nil
|
data.attrs = nil
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
slf.messageChannel = map[int]chan *message{}
|
slf.messageChannel = map[int]chan *Message{}
|
||||||
for i := 0; i < slf.core; i++ {
|
for i := 0; i < slf.core; i++ {
|
||||||
slf.messageChannel[i] = make(chan *message, 4096*1000)
|
slf.messageChannel[i] = make(chan *Message, 4096*1000)
|
||||||
}
|
}
|
||||||
if slf.network != NetworkHttp && slf.network != NetworkWebsocket {
|
if slf.network != NetworkHttp && slf.network != NetworkWebsocket {
|
||||||
slf.gServer = &gNet{Server: slf}
|
slf.gServer = &gNet{Server: slf}
|
||||||
|
@ -420,15 +420,19 @@ func (slf *Server) PushCrossMessage(crossName string, serverId int64, packet []b
|
||||||
}
|
}
|
||||||
|
|
||||||
// dispatchMessage 消息分发
|
// dispatchMessage 消息分发
|
||||||
func (slf *Server) dispatchMessage(msg *message) {
|
func (slf *Server) dispatchMessage(msg *Message) {
|
||||||
present := time.Now()
|
present := time.Now()
|
||||||
defer func() {
|
defer func() {
|
||||||
if err := recover(); err != nil {
|
if err := recover(); err != nil {
|
||||||
log.Error("Server", zap.String("MessageType", messageNames[msg.t]), zap.Any("MessageAttrs", msg.attrs), zap.Any("error", err))
|
log.Error("Server", zap.String("MessageType", messageNames[msg.t]), zap.Any("MessageAttrs", msg.attrs), zap.Any("error", err))
|
||||||
|
if e, ok := err.(error); ok {
|
||||||
|
slf.OnMessageErrorEvent(msg, e)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if cost := time.Since(present); cost > time.Millisecond*100 {
|
if cost := time.Since(present); cost > time.Millisecond*100 {
|
||||||
log.Warn("Server", zap.String("MessageType", messageNames[msg.t]), zap.String("LowExecCost", cost.String()), zap.Any("MessageAttrs", msg.attrs))
|
log.Warn("Server", zap.String("MessageType", messageNames[msg.t]), zap.String("LowExecCost", cost.String()), zap.Any("MessageAttrs", msg.attrs))
|
||||||
|
slf.OnMessageLowExecEvent(msg, cost)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !slf.isShutdown.Load() {
|
if !slf.isShutdown.Load() {
|
||||||
|
|
Loading…
Reference in New Issue