popiart-server
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

3.7 KiB

popiartServer 薄膜持久化设计

这份文档描述当前的轻量化持久化方案。目标不是把 popiartServer 做成第二个模型平台,而是让它只保存 PopiArt 自己的产品语义。

设计原则

PopiNewAPI 已经负责:

  • 上游 provider key
  • 模型请求
  • 原始用量
  • 一部分任务型能力的 task 状态

所以 popiartServer 不再重复持有:

  • 本地 artifact blob store
  • 本地 artifact metadata table
  • 本地 job_logs table

它只保留三类本地状态:

  • sessions
  • jobs(更准确说是 job refs)
  • skill_routes

当前关系

session -> jobs
jobs    -> result_refs_json
project -> skill_routes

其中:

  • session 保存 PopiArt 登录态和对应的 PopiNewAPI token
  • jobs 保存 skill 语义、用户归属、上游引用和同步结果引用
  • result_refs_json 保存同步能力的返回引用,例如 data_url 或远端 url
  • skill_routes 保存项目级路由覆盖

存储位置

默认配置来自这些环境变量:

  • POPIART_DATA_DIR
  • POPIART_SQLITE_PATH
  • POPIART_SESSION_SECRET

默认值:

POPIART_DATA_DIR=./data
POPIART_SQLITE_PATH=./data/popiart.db

Repository 接口

代码位置:

  • internal/server/repository.go

当前只保留三层 repository:

  1. SessionRepository
  2. JobRepository
  3. RouteRepository

没有单独的 blob storage 抽象。

SQLite Schema

sessions

CREATE TABLE sessions (
  session_id TEXT PRIMARY KEY,
  user_id TEXT NOT NULL,
  user_json TEXT NOT NULL,
  token_enc BLOB NOT NULL,
  token_masked TEXT NOT NULL,
  created_at TEXT NOT NULL,
  expires_at TEXT NOT NULL
);

jobs

CREATE TABLE jobs (
  job_id TEXT PRIMARY KEY,
  user_id TEXT NOT NULL,
  session_id TEXT,
  project_id TEXT,
  skill_id TEXT,
  route_key TEXT,
  model_id TEXT,
  exec_mode TEXT NOT NULL,
  newapi_task_id TEXT,
  status TEXT NOT NULL,
  input_json TEXT NOT NULL,
  result_refs_json TEXT,
  usage_json TEXT,
  error_json TEXT,
  idempotency_key TEXT,
  created_at TEXT NOT NULL,
  started_at TEXT,
  finished_at TEXT,
  UNIQUE(user_id, idempotency_key)
);

skill_routes

CREATE TABLE skill_routes (
  route_key TEXT NOT NULL,
  scope_key TEXT NOT NULL,
  model_id TEXT NOT NULL,
  options_json TEXT,
  updated_at TEXT NOT NULL,
  PRIMARY KEY(route_key, scope_key)
);

运行时流程

登录

  1. CLI 把 PopiNewAPI token 交给 popiartServer
  2. popiartServer/v1/models 验证 token
  3. server 签发本地 sess_xxx
  4. 本地 session 持久化到 SQLite,重启后仍可继续使用

创建 job

  1. server 解析 skill_id -> route_key -> model_id
  2. jobs 表写入一条本地 job ref
  3. goroutine 开始向 PopiNewAPI 发请求

完成同步结果 job

  1. 如果 PopiNewAPI 直接返回同步结果,例如 b64_jsonurl
  2. popiartServer 只把它转换成 result_refs_json
  3. GET /jobs/:id/artifacts 时再从 result_refs_json 派生 artifact 列表

拉取 artifact

  1. server 从 artifact_id 反推出 job_id + result index
  2. 读取 jobs.result_refs_json
  3. 如果是 data_url,直接解码并流式返回
  4. 如果是远端 url,server 代理下载并返回

当前边界

  • server 重启后:
    • session 会保留
    • job ref 会保留
    • artifact 通过 result_refs_json 继续可读
  • 已存在的 pending/running job 仍然不会自动恢复执行
  • 视频类 upstream_task 路径只预留了字段,后续再接 PopiNewAPI task 查询
  • 对同步图像结果来说,data_url 仍然会落在 SQLite 的 result_refs_json 这是当前 PopiNewAPI 没有统一 file id 的现实折中,但已经不再有本地 artifact 表和 blob store