Vivid

创建与生命周期

Actor 的创建方式、生命周期状态与系统消息(含 Prelaunch、OnLaunch/OnKill/OnKilled)、发起终止

本文说明 Actor 的创建方式生命周期发起终止:如何创建根/子 Actor、生命周期中的预启动与系统消息、如何发起终止。Watch/Unwatch、主动上报故障、僵尸状态、ActorRef 与从字符串解析、组合多个 Actor 见各专题。实现方式见 实现 Actor,创建时选项见 Actor 配置

创建与层级

创建方式:系统级与上下文中
加载图表…

系统级创建(根 Actor)

在程序入口通常只创建一个 ActorSystem,再在系统上创建根 Actor

system := bootstrap.NewActorSystem()
// ...
ref, err := system.ActorOf(&MyActor{}, vivid.WithActorName("root"))
  • system.ActorOf(actor, options...)并发安全,可在多 goroutine 中调用。
  • 返回的 ActorRef 用于后续 Tell/Ask、传给其他 Actor 或查找。

在上下文中创建子 Actor

在某个 Actor 的 OnReceive 内,通过 ActorContext 创建子 Actor

childRef, err := ctx.ActorOf(&WorkerActor{}, vivid.WithActorName("worker-1"))
  • 子 Actor 的父级为当前 ctx.Ref(),生命周期由当前 Actor 管理。
  • 父级会自动 Watch 子级,子级终止时父级会收到 *vivid.OnKilled,无需手动 Watch;该监听由父子关系绑定,父 Actor 无法对子 Actor 调用 Unwatch 取消。主动监听非子级 Actor 的终止见 Watch 与 Unwatch
  • 同一父级下子 Actor 名称必须唯一;不指定名称时系统会自动分配。
  • 创建成功后,子 Actor 会经历预启动(Prelaunch)(若实现),再收到 *vivid.OnLaunch,然后开始接收业务消息。ctx.Children() 返回当前已创建的子 Actor 引用列表(快照),可用于批量 Tell、监控或监督逻辑。

并发限制

ctx.ActorOf 非并发安全。不要在多个 goroutine 中并发创建同一父级下的子 Actor,应在单次消息处理内或串行逻辑中创建。

命名与配置

  • WithActorName(name):指定名称,同父下唯一;不传则系统自动生成。
  • 其他创建时选项(邮箱、默认 Ask 超时、Logger、监督策略、Provider 等)见 Actor 配置

创建失败与错误

ActorOf 可能返回 ErrorActorAlreadyExists(同父下名称重复)、ErrorActorSpawnFailed(创建或预启动失败)、ErrorActorDeaded(在已死亡的父级上创建)等。可用 errors.Is(err, vivid.ErrorActorAlreadyExists) 等方式判定。错误体系见 错误


生命周期概览

单个 Actor 的状态流转:

单个 Actor 生命周期状态
加载图表…

父子与终止、OnKilled:父创建子后,子经历上述生命周期;子被 Kill 或故障终止后,父级会收到 OnKilled(Ref 为该子)。父自身终止时也会在流程中收到 Ref 为自己的 OnKilled。

子 Actor 创建、销毁与父级收到 OnKilled
加载图表…

OnReceive 中可通过类型断言区分系统消息与业务消息:

消息类型含义
*vivid.OnLaunch启动后收到的第一条业务前消息,用于初始化
*vivid.OnKill收到终止请求,可做优雅收尾
*vivid.OnKilled某 Actor 已终止的通知(Ref 为被终止的 Actor),用于清理或通知

Prelaunch 与 OnLaunch 的区别

维度Prelaunch(OnPrelaunch)OnLaunch
时机在 Actor 正式“启动”之前,尚未开始接收消息启动后收到的第一条消息,已具备完整邮箱与上下文
上下文PrelaunchContext(Logger、Ref),不能 Tell/ActorOf/WatchActorContext 完整可用,可发消息、创建子 Actor、订阅等
典型场景配置校验、环境检查、依赖注入、预加载只读数据;任一失败可令启动中止(返回 error)向注册中心注册、订阅 EventStream、创建子 Actor、发起首次 Tell/调度;需要与系统其它部分交互的“上线”逻辑
失败后果返回 error → Actor 不启动,ActorOf 返回错误若在此 panic 或 Failed,由父级监督策略处理(如重启)

简单划分:仅做校验与准备、且不需发消息或创建子 Actor 时用 Prelaunch需要与系统其它 Actor 或组件交互的“上线”逻辑放在 OnLaunch


启动阶段

Prelaunch

首次创建与启动时,若 Actor 实现了 PrelaunchActor,系统会在投递 OnLaunch 之前先调用 OnPrelaunch,用于依赖注入、配置校验、资源预加载等。该阶段在生命周期图中对应「预启动」。

接口方法调用时机
PrelaunchActorOnPrelaunch(ctx PrelaunchContext) error正式启动前(在 OnLaunch 之前);返回 error 则启动失败

PrelaunchContext 提供 Logger()Ref();不提供消息发送、子 Actor 创建等运行时能力。不定义新类型时可用 vivid.NewPrelaunchActor(prelaunchFn, actor) 挂载预启动逻辑;未传入的 actor 使用占位空实现。


运行阶段

OnLaunch

Actor 通过预启动(若有)并完成创建后,收到的第一条系统消息。此时已有完整 ActorContext(可 Tell/Ask、ActorOf、Watch、EventStream、Scheduler 等),适合做需要运行时上下文的操作:向外部或本系统其它 Actor 注册自己、订阅事件流、创建子 Actor、调度首次任务等。

OnKill

收到 *vivid.OnKill 时,可读取以下字段并做收尾:

字段说明
Killer发起终止请求的 ActorRef
Reason终止原因描述,便于日志记录与问题定位
Poisonfalse 为立即终止(OnKill 作为系统消息投递,不处理剩余用户消息队列);true 为毒丸模式(OnKill 作为用户消息入队,处理完当前与队列中的用户消息后再处理 OnKill 并终止)

收到 OnKill 时,终止已经注定开始,msg.Poison 仅表示本次是以何种方式被请求终止(立即或毒丸),用于日志或收尾策略参考;无法通过代码改变终止方式,只能根据字段做相应清理或记录。

示例:

case *vivid.OnKill:
    // 根据 Poison / Reason 决定收尾粒度或打日志;终止流程由框架继续
    if msg.Poison { /* 本次为毒丸模式 */ } else { /* 本次为立即终止 */ }

OnKilled

*vivid.OnKilled 表示“某 Actor 已终止”,当前 Actor 会在以下情况收到:

  • 自己:终止流程中会收到一条 Ref 为自己的 OnKilled。
  • 子 Actor:父级自动监听子级,子级终止时父级收到,Ref 为该子 Actor。
  • 通过 Watch 监听的 Actor:被监听者终止时收到,Ref 为被监听的 Actor。

消息中的 Ref 为被终止的 Actor 引用,可根据 Ref 判断是谁终止,并做清理、重新创建或告警。主动监听非子级 Actor 见 Watch 与 Unwatch


发起终止(Kill)

向指定 ActorRef 发送终止请求:框架会向该 Actor 投递 *vivid.OnKill,目标可在 OnReceive 中处理并做优雅收尾。

ctx.Kill(targetRef, poison, "reason")
// 或
system.Kill(targetRef, poison, "reason")
  • poisonfalse 立即终止(不处理剩余队列);true 毒丸模式(处理完当前与队列中的消息后再终止)。
  • reason:可变参数,会拼接为字符串写入 OnKill.Reason
  • 终止请求异步,调用后立即返回;目标终止后会向所有 Watch 该 ref 的 Actor 发送 OnKilled。监听其他 Actor 终止见 Watch 与 Unwatch

相关专题

On this page