core

package
v0.0.0-...-2439b48 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 2, 2026 License: Apache-2.0 Imports: 14 Imported by: 0

Documentation

Index

Constants

View Source
const (
	AppStateNone = iota // 应用未启动或已完全停止,可安全重新启动
	AppStateInit        // 应用正在初始化,所有模块的 OnInit 正在按序执行
	AppStateRun         // 应用运行中,所有模块已成功启动并处于活跃状态
	AppStateStop        // 应用正在优雅关闭,模块正按逆序依次停止
)

应用全局状态常量,表示应用生命周期的各个阶段。

Variables

This section is empty.

Functions

func AddDynamicModules

func AddDynamicModules(mods ...IModule) error

AddDynamicModules 向运行中的全局默认应用实例动态添加并启动一批模块。

动态模块支持热加载,模块在 OnInit 成功后立即启动,无需重启整个应用。 动态模块的 panic 不会导致进程退出,且可通过 RemoveDynamicModule 单独卸载。

func DynamicModules

func DynamicModules() []string

DynamicModules 返回全局默认应用实例中当前所有动态模块的名称列表。

用于运维监控、热加载管理等场景,列表顺序不保证与注册顺序一致(sync.Map 无序)。

func GetChanRPC

func GetChanRPC(name string) *chanrpc.Server

GetChanRPC 通过模块名称获取对应模块的 ChanRPC 服务端,用于跨模块消息投递。

优先在静态模块中查找,未命中则查找动态模块。 返回 nil 表示对应模块不存在或不支持 RPC,调用方可据此做降级处理(如 Cast 时静默丢弃)。

func GetState

func GetState() int32

GetState 获取全局默认应用实例的当前运行状态。

返回值为 AppStateNone/AppStateInit/AppStateRun/AppStateStop 之一, 可用于在关闭信号处理逻辑中判断当前是否可以安全发起操作。

func Register

func Register(mods ...IModule) error

Register 向全局默认应用实例注册静态模块。

必须在 Run 调用之前完成注册。若应用已处于运行状态则返回错误。 运行中需要动态增减模块请使用 AddDynamicModules 和 RemoveDynamicModule。

func RemoveDynamicModule

func RemoveDynamicModule(name string) bool

RemoveDynamicModule 从全局默认应用实例中同步移除并销毁指定名称的动态模块。

操作为同步阻塞:cancel(发停止信号)→ wg.Wait(等待 goroutine 退出)→ OnDestroy(清理资源)→ 从 map 移除。 调用方会等待模块完全停止后才返回,确保所有资源在函数返回前已被完整清理。

func Run

func Run(mods ...IModule)

Run 向全局默认应用实例注册模块并启动,同时监听系统退出信号(SIGINT/SIGTERM)。

函数会阻塞当前 goroutine 直至收到退出信号,收到后执行优雅关闭流程。 适合在 main 函数中直接调用,是应用的主入口点。 SIGHUP 信号不会触发关闭,可用于通知应用重新加载配置(业务层自行监听处理)。

func Stats

func Stats() string

Stats 获取全局默认应用实例中所有模块(静态 + 动态)的 RPC 队列积压状态统计字符串。

输出内容可直接用于监控告警或定期日志打印,帮助快速定位消息积压瓶颈。

Types

type IModule

type IModule interface {
	Name() string                // 模块唯一名称,用于日志标识和跨模块 RPC 寻址
	OnInit() error               // 模块初始化,任一模块失败则终止整个应用启动流程
	OnStart(ctx context.Context) // 模块主循环,应监听 ctx.Done() 并在收到取消信号时退出
	OnDestroy()                  // 模块销毁,在 goroutine 完全退出后调用,负责释放所有资源
	ChanRPC() *chanrpc.Server    // 返回模块的 ChanRPC 服务端,nil 表示该模块不接受外部 RPC 调用
}

IModule 定义应用模块的完整生命周期接口。

框架通过此接口管理模块从初始化到销毁的全过程,每个模块代表一个独立的业务单元, 拥有独立的 goroutine、RPC 服务端和定时器管理器。 模块之间通过 ChanRPC 通信,天然隔离内部状态,无需跨模块加锁。

type IRPC

type IRPC interface {
	// Cast 单向消息投递,不等待结果,适合日志上报、事件通知等不需要响应的场景。
	Cast(mod string, req any)
	// Call 同步 RPC 调用,阻塞等待对端处理完成并返回结果。
	// 警告:若调用链形成环(A→B→A),将导致死锁,生产环境应优先使用 AsyncCall。
	Call(mod string, req any) *chanrpc.RetInfo
	// AsyncCall 异步 RPC 调用,立即返回,结果通过 cb 回调在调用方 goroutine 处理。
	// 回调在事件循环中串行执行,可安全访问模块内部状态,无需加锁。
	AsyncCall(mod string, req any, cb chanrpc.Callback) error
}

IRPC 定义跨模块 RPC 调用的接口,提供三种调用语义覆盖不同并发场景。

调用模式对比:

  • Cast:单向投递,无响应,吞吐最高,适合通知/事件
  • AsyncCall:异步调用,回调在调用方 goroutine 执行,无锁安全,推荐使用
  • Call:同步阻塞,有死锁风险,仅在确认无循环依赖时使用

type ITimer

type ITimer interface {
	// RegisterTimer 注册指定类型定时器的处理函数,同 kind 仅能注册一个处理器(后注册覆盖前者)。
	RegisterTimer(kind string, handler timermgr.TimerHandler)
	// NewTimer 创建一次性定时器,duraMs 毫秒后触发一次,返回定时器 ID。
	NewTimer(duraMs int64, kind string, metadata map[string]string) int64
	// NewTicker 创建周期性定时器,每隔 duraMs 毫秒触发一次,返回定时器 ID。
	NewTicker(duraMs int64, kind string, metadata map[string]string) int64
	// AccTimer 加速指定定时器,提前其触发时间。
	AccTimer(id int64, kind timermgr.AccKind, value int64) error
	// DelayTimer 延迟指定定时器,推迟其触发时间。
	DelayTimer(id int64, kind timermgr.AccKind, value int64) (err error)
	// CancelTimer 取消指定 ID 的定时器,对已触发或已取消的定时器调用是安全的(幂等)。
	CancelTimer(id int64)
}

ITimer 定义定时器管理接口,支持一次性定时器和周期性 Ticker 的完整生命周期管理。

type Skeleton

type Skeleton struct {
	// contains filtered or unexported fields
}

Skeleton 模块骨架,将 ChanRPC(服务端/客户端)和定时器管理器整合为统一的事件驱动框架。

核心设计思想(Actor 模型): 所有事件(RPC 调用、异步回调、定时器)在单一 goroutine(OnStart)中串行处理, 彻底消除模块内部的并发竞争,开发者无需为访问模块状态加任何锁,极大降低了复杂度。

使用方式:业务模块内嵌 Skeleton,重写 OnInit 注册处理函数,重写 OnDestroy 清理资源, 无需重写 OnStart 和 ChanRPC(Skeleton 已提供默认实现)。

func NewSkeleton

func NewSkeleton(name string) *Skeleton

NewSkeleton 创建模块骨架,初始化 ChanRPC 和定时器组件。

各组件缓冲区均为 10000,适合高并发游戏服务器场景下的消息吞吐需求。 若某模块的消息量远超此值,需根据业务峰值流量调整,过小会导致背压和调用方超时。

func (*Skeleton) AccTimer

func (s *Skeleton) AccTimer(id int64, kind timermgr.AccKind, value int64) error

AccTimer 按指定方式加速定时器,提前其触发时间。

func (*Skeleton) AsyncCall

func (s *Skeleton) AsyncCall(mod string, req any, cb chanrpc.Callback) error

AsyncCall 向指定模块发起异步 RPC 调用,结果通过 cb 回调在本模块事件循环中执行。

回调在 OnStart 的 select 循环中消费 ChanAsyncRet 时执行, 与模块其他事件处理串行,无并发问题,可安全访问模块内部状态。

func (*Skeleton) Call

func (s *Skeleton) Call(mod string, req any) *chanrpc.RetInfo

Call 向指定模块发起同步 RPC 调用,阻塞当前模块的事件处理直到收到响应。

危险提示:Call 会阻塞本模块对其他消息的处理; 若 A 调用 B,同时 B 也在等待 A 的响应,则形成死锁,需通过仔细的调用关系分析来规避。 在事件循环中应优先使用 AsyncCall,仅在调用关系明确单向且不存在环路时才使用 Call。

func (*Skeleton) CancelTimer

func (s *Skeleton) CancelTimer(id int64)

CancelTimer 取消指定 ID 的定时器,同时清理业务层元数据,对已触发/已取消的定时器调用安全(幂等)。

func (*Skeleton) Cast

func (s *Skeleton) Cast(mod string, req any)

Cast 向指定模块投递单向消息,不等待响应,适合日志记录、事件通知等无需确认的场景。

func (*Skeleton) ChanRPC

func (s *Skeleton) ChanRPC() *chanrpc.Server

ChanRPC 返回模块的 ChanRPC 服务端,供框架注册到模块映射表,以及外部模块通过 GetChanRPC 获取后投递消息。

func (*Skeleton) DelayTimer

func (s *Skeleton) DelayTimer(id int64, kind timermgr.AccKind, value int64) (err error)

DelayTimer 按指定方式延迟定时器,推迟其触发时间。

func (*Skeleton) Name

func (s *Skeleton) Name() string

Name 返回模块名称,实现 IModule.Name 接口。

func (*Skeleton) NewTicker

func (s *Skeleton) NewTicker(id int64, duraMs int64, kind string, metadata map[string]string) int64

NewTicker 创建周期性定时器,每隔 duraMs 毫秒触发一次,触发后自动续期直到被取消。

id 为 0 时自动生成新 ID;传入已有 ID 时复用该定时器(覆盖更新周期), 可用于动态调整已有 Ticker 的触发频率,无需先取消再重建。

func (*Skeleton) NewTimer

func (s *Skeleton) NewTimer(duraMs int64, kind string, metadata map[string]string) int64

NewTimer 创建一次性定时器,duraMs 毫秒后触发一次,自动生成 ID。

func (*Skeleton) OnStart

func (s *Skeleton) OnStart(ctx context.Context)

OnStart 启动模块事件循环,阻塞至 ctx 被取消(即框架调用 cancel)。

事件循环采用 select 多路复用以下三类事件,保证在单一 goroutine 内串行处理:

  1. ctx.Done():接收框架的停止信号,触发模块关闭流程
  2. ChanAsyncRet:处理本模块发起的异步 RPC 调用的返回结果(执行注册的 Callback)
  3. ChanCall:处理其他模块发来的 RPC 调用请求(查找并执行已注册的 Handler)
  4. ChanTimer:处理到期的定时器事件(执行注册的 TimerHandler,并自动续期 Ticker)

单 goroutine 串行处理是性能与正确性权衡的结果: 牺牲了 CPU 并行利用率,换取了零锁开销和极低的编程复杂度。

func (*Skeleton) RegisterChanRPC

func (s *Skeleton) RegisterChanRPC(msg any, f chanrpc.Handler) error

RegisterChanRPC 注册 RPC 消息处理函数,通过 msg 的类型自动推导消息 ID 并完成路由注册。

通常在 OnInit 中批量注册,注册完成后路由表不再变更,访问无需加锁。

func (*Skeleton) RegisterTimer

func (s *Skeleton) RegisterTimer(kind string, handler timermgr.TimerHandler)

RegisterTimer 注册指定 kind 类型的定时器处理函数,通常在 OnInit 中调用完成所有注册。

Directories

Path Synopsis
Package timermgr 提供基于多级时间轮算法的高性能定时器调度系统。
Package timermgr 提供基于多级时间轮算法的高性能定时器调度系统。

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL