实现 Actor
Actor 接口、结构体与函数式实现
本文说明如何实现一个可被系统调度的 Actor:实现 vivid.Actor 接口、在 OnReceive 中处理消息,结构体与函数式两种写法。创建与生命周期见 创建与生命周期;运行时通过行为栈切换处理逻辑见 行为栈。
Actor 接口
可被调度的 Actor 必须实现 vivid.Actor 接口:
type Actor interface {
OnReceive(ctx ActorContext)
}框架在每次向该 Actor 投递消息时,会调用当前行为(默认即为该 OnReceive),并注入当次消息对应的 ActorContext。在 OnReceive 内应通过 ctx.Message() 获取当前消息并做类型分支处理。当前 Actor 的引用可通过 ctx.Ref() 获取,便于在组合 Actor 或向子 Actor、调度器传递自身引用。若在处理过程中发生 panic,框架会捕获并视为该 Actor 的故障,交由父级的 监督策略 处理(等同于主动调用 Failed);因此应尽量在业务逻辑中恢复可预期错误,或显式调用 ctx.Failed(fault) 上报。
实现方式
结构体实现
推荐用结构体实现 Actor,便于携带状态与依赖:
type MyActor struct {
dependency SomeService
}
func (a *MyActor) OnReceive(ctx vivid.ActorContext) {
switch msg := ctx.Message().(type) {
case *vivid.OnLaunch:
// 初始化
case *MyRequest:
ctx.Reply(a.dependency.Handle(msg))
default:
// 忽略或记录未知类型
}
}同一类型的不同实例可被多次创建为不同 Actor,彼此状态隔离。
函数式实现(ActorFN)
无状态或逻辑简单时,可使用 vivid.ActorFN,无需定义新类型:
actor := vivid.ActorFN(func(ctx vivid.ActorContext) {
if msg, ok := ctx.Message().(string); ok {
ctx.Reply("got: " + msg)
}
})适用于一次性、无状态的处理器;需要状态时请用结构体实现。运行时通过 Become / UnBecome 切换消息处理逻辑见进阶 行为栈。