跳转到内容

Worker Service 后台服务模式

Worker Service 后台服务模式:Claude-Mem 的具体实现

学习目标

本章聚焦 Claude-Mem 的 Worker Service 如何作为 Bun 管理的后台 HTTP 服务运行。建议先阅读前置知识,下文直接聚焦具体落地方案。

项目实践

架构概览

worker-service.ts(约 46KB)是 Claude-Mem 的核心后台服务,基于 Express 5 构建 HTTP API:

端口分配策略

Worker Service 的默认端口基于 OS UID 计算,自动避免冲突:

port = 37700 + (uid % 100)

两个不同 OS 用户在同一台机器上运行,自动获得不同端口。用户可通过 CLAUDE_MEM_WORKER_PORT 环境变量强制指定端口。

进程管理

Worker 通过 PID 文件管理进程生命周期:

操作实现
启动写入 PID 文件,检查端口占用
状态读取 PID 文件,验证进程存在且端口匹配
停止读取 PID 文件,发送 SIGTERM,清理 PID 文件
重启停止 + 启动
陈旧清理验证 PID 文件所有者,清理不属于当前用户的 PID

Supervisor 模式

src/supervisor/ 实现了 Supervisor 监控:

  • 心跳检测:每 30 秒检查父进程 PID,检测孤儿进程
  • 进程注册表:跟踪所有子进程的状态
  • 优雅关闭:接收 SIGTERM/SIGINT 后执行清理流程
  • 环境净化:启动前清理环境变量,避免污染

多账户隔离

通过 CLAUDE_MEM_DATA_DIR 环境变量支持多账户:

Terminal window
export CLAUDE_MEM_DATA_DIR="$HOME/.claude-mem-work"

所有路径(数据库、Chroma、日志、配置、PID 文件)都基于该目录派生:

$CLAUDE_MEM_DATA_DIR/
├── claude-mem.db # SQLite 数据库
├── chroma/ # Chroma 向量数据
├── logs/ # Worker 日志
├── settings.json # 配置文件
└── worker.pid # PID 文件

依赖自动安装

Worker Service 在启动时检查依赖:

  • Bun:JS 运行时,缺失时通过 curl 安装脚本自动安装
  • uv:Python 包管理器(用于 Chroma),缺失时自动安装

HTTP API 路由分类

路由前缀功能
/api/search记忆搜索(FTS5 + 格式化)
/api/timeline时间线上下文
/api/observations/batch批量获取观察详情
/api/corpus知识语料库 CRUD
/api/health健康检查
/v1/*Server-Beta REST API
/sseServer-Sent Events
/auth/*BetterAuth 认证

问题与规避

端口冲突

问题:两个 Worker 实例尝试绑定同一端口。

规避:启动时通过 isPortInUse() 检查端口,已占用时返回 'dead' 状态,调用方据此报告错误。UID 基础端口计算降低了同一机器上冲突的概率。

Windows 终端标签页累积

问题:Hook 非零退出码可能导致 Windows Terminal 为每次失败打开新标签页。

规避:Worker/Hook 默认 Exit 0(即使有 ERROR 级别日志),通过 stderr 输出错误信息但不触发终端行为。包装层/插件负责重启逻辑。

设计取舍

为什么用 Express 而非 Bun 原生 HTTP?

  • 优势:Express 5 提供了成熟的中间件生态、路由参数解析、错误处理
  • 代价:额外的依赖
  • 权衡:BetterAuth(认证框架)也依赖 Express 生态,选择 Express 可以复用中间件

参考来源