Code Reader
首页
帮助
设计文档
首页
帮助
设计文档
  • SessionStatus

SessionStatus

SessionStatus 管理会话的运行状态。

概述

SessionStatus 跟踪会话的当前状态(空闲、重试中、忙碌),用于协调 UI 显示和防止并发操作。

定义位置

packages/opencode/src/session/status.ts:7-25

主要对象

Info

会话状态信息(联合类型)。

Idle 状态

{
  type: "idle"
}

表示会话空闲,可以接受新输入。

Retry 状态

{
  type: "retry"
  attempt: number
  message: string
  next: number
}

表示会话正在重试失败的操作。

属性名类型必填说明
type"retry"是类型标识
attemptnumber是当前尝试次数
messagestring是重试原因/消息
nextnumber是下次重试延迟(毫秒)

Busy 状态

{
  type: "busy"
}

表示会话正在处理,不能接受新输入。

TypeScript 类型定义

export type Info =
  | { type: "idle" }
  | {
      type: "retry"
      attempt: number
      message: string
      next: number
    }
  | { type: "busy" }

事件

事件名类型说明
session.status{sessionID, status: Info}会话状态更新
session.idle{sessionID} (已废弃)会话进入空闲状态

典型使用场景

1. 获取会话状态

const status = SessionStatus.get(sessionStatusID)

console.log(status.type) // "idle" | "retry" | "busy"

if (status.type === "retry") {
  console.log(`Attempt ${status.attempt}: ${status.message}`)
  console.log(`Next retry in ${status.next}ms`)
}

2. 设置会话为忙碌

SessionStatus.set(sessionID, {
  type: "busy",
})

// 发布 session.status 事件

3. 设置会话为空闲

SessionStatus.set(sessionID, {
  type: "idle",
})

// 自动清除状态,发布 session.status 和 session.idle 事件

4. 设置重试状态

SessionStatus.set(sessionID, {
  type: "retry",
  attempt: 3,
  message: "API rate limited",
  next: 5000, // 5 秒后重试
})

5. 列出所有会话状态

const allStatus = SessionStatus.list()

for (const [sessionID, status] of Object.entries(allStatus)) {
  console.log(`${sessionID}: ${status.type}`)
}

状态转换图

状态使用场景

防止并发操作

const' status = SessionStatus.get(sessionID)

if (status.type === "busy") {
  console.log("Session is busy, please wait")
  return
}

// 安全地执行操作
SessionStatus.set(sessionID, { type: "busy" })
try {
  await performOperation()
} finally {
  SessionStatus.set(sessionID, { type: "idle" })
}

UI 状态显示

Bus.subscribeAll(async (event) => {
  if (event.type === "session.status") {
    const { sessionID, status } = event.properties

    switch (status.type) {
      case "idle":
        updateUI({ status: "ready", icon: "check" })
        break
      case "busy":
        updateUI({ status: "processing", icon: "spinner" })
        break
      case "retry":
        updateUI({
          status: "retrying",
          icon: "retry",
          message: `Attempt ${status.attempt}`,
        })
        break
    }
  }
})

重试逻辑

async function withRetry<T>(sessionID: string, fn: () => Promise<T>, maxAttempts = 3): Promise<T> {
  let attempt = 0

  while (attempt < maxAttempts) {
    attempt++

    try {
      return await fn()
    } catch (error) {
      if (attempt >= maxAttempts) {
        throw error
      }

      // 计算重试延迟(指数退避)
      const delay = Math.pow(2, attempt) * 1000

      // 设置重试状态
      SessionStatus.set(sessionID, {
        type: "retry",
        attempt,
        message: error.message,
        next: delay,
      })

      // 等待
      await new Promise((resolve) => setTimeout(resolve, delay))
    }
  }

  throw new Error("Max attempts exceeded")
}

状态管理

内存存储

const state = Instance.state(() => {
  const data: Record<string, Info> = {}
  return data
})

状态持久化

SessionStatus 是运行时状态,不持久化到磁盘。重启后会话默认为 idle。

自动清理

当会话设置为 idle 时:

if (status.type === "idle") {
  // 清理状态
  delete state()[sessionID]

  // 发布已废弃的 idle 事件
  Bus.publish(Event.Idle, { sessionID })
}

错误处理

无效状态转换

// 不允许从 idle 直接到 retry
if (current.type === "idle" && newStatus.type === "retry") {
  throw new Error("Invalid state transition: idle -> retry")
}

对象关系

变更历史

版本变更内容日期
v1初始 SessionStatus 架构-
v1.1添加 retry 状态支持-

相关文档

  • Session - 会话对象
  • Events - 事件系统