vRp.CD2g_test/server/writeloop/channel.go

57 lines
1.5 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package writeloop
import (
"github.com/kercylan98/minotaur/utils/hub"
"github.com/kercylan98/minotaur/utils/log"
)
// NewChannel 创建基于 Channel 的写循环
// - pool 用于管理 Message 对象的缓冲池,在创建 Message 对象时也应该使用该缓冲池,以便复用 Message 对象。 Channel 会在写入完成后将 Message 对象放回缓冲池
// - channelSize Channel 的大小
// - writeHandler 写入处理函数
// - errorHandler 错误处理函数
//
// 传入 writeHandler 的消息对象是从 Channel 中获取的,因此 writeHandler 不应该持有消息对象的引用,同时也不应该主动释放消息对象
func NewChannel[Message any](pool *hub.ObjectPool[Message], channelSize int, writeHandler func(message Message) error, errorHandler func(err any)) *Channel[Message] {
wl := &Channel[Message]{
c: make(chan Message, channelSize),
}
go func() {
for {
select {
case message, ok := <-wl.c:
if !ok {
return
}
err := writeHandler(message)
pool.Release(message)
if err != nil {
if errorHandler == nil {
log.Error("Channel", log.Err(err))
continue
}
errorHandler(err)
}
}
}
}()
return wl
}
// Channel 基于 chan 的写循环,与 Unbounded 相同,但是使用 Channel 实现
type Channel[T any] struct {
c chan T
}
// Put 将数据放入写循环message 应该来源于 hub.ObjectPool
func (slf *Channel[T]) Put(message T) {
slf.c <- message
}
// Close 关闭写循环
func (slf *Channel[T]) Close() {
close(slf.c)
}