Skip to content

Conversation

@YangQing-Lin
Copy link
Collaborator

目标 / 背景

当前 Session 的 Redis 绑定/续期统一使用全局 SESSION_TTL(默认 300s)。在多供应商场景下,不同上游对“会话粘性/上下文缓存窗口”的需求不同:

  • 部分上游希望更长的粘性窗口来提升命中率与稳定性
  • 部分上游希望更短的窗口来降低切换成本或避免长期粘性

因此需要允许在 Provider 维度覆写 Session TTL,并在 Redis 侧按绑定的 Provider TTL 进行过期控制。(#603)

方案概述

  • providers 表新增可空字段 session_ttl(秒)。
  • Provider CRUD / 类型 / 校验贯通 session_ttl
  • 在 Session 绑定与刷新处使用“provider 优先、全局兜底”的 TTL 解析,并限制在 60~3600 秒。

变更点

数据库

  • providers.session_ttl(integer, nullable):drizzle/0055_normal_johnny_storm.sql

后端(Provider 配置贯通)

  • src/lib/validation/schemas.ts:Create/Update Provider schema 增加 session_ttl,并强制为整数且范围 60~3600。
  • src/types/provider.ts:新增 Provider.sessionTtlProviderDisplay.sessionTtl,并在 CreateProviderData/UpdateProviderData 支持 session_ttl?: number | null
  • src/repository/provider.ts / src/repository/_shared/transformers.ts:DB ↔ 领域模型映射新增 sessionTtl

Session / Redis 行为

  • src/lib/session-manager.ts
    • resolveSessionTtl(providerTtl):provider ttl 优先;否则使用全局 SESSION_TTL(无效则 300);最终 clamp 到 60~3600。
    • resolveSessionTtlForSession(sessionId):读取 session:{id}:provider 绑定的 providerId,回查 Provider 配置得到最终 ttl,用于刷新。
    • bindSessionToProvider / updateSessionBindingSmart / updateSessionWithCodexCacheKey:写入/续期 session:{id}:provider 时使用该 ttl。
  • src/lib/session-tracker.ts
    • refreshSession(sessionId, keyId, providerId, ttlSeconds):用传入 ttl 刷新 session:{id}:providersession:{id}:keysession:{id}:last_seen 的过期时间(原先固定 300s)。
    • 说明:活跃 Session 统计窗口仍为 5 分钟(ZSET 清理逻辑不变),本 PR 仅调整会话绑定/续期 key 的 TTL。

Proxy 集成点

  • src/app/v1/_lib/proxy/forwarder.ts:成功后绑定 Session 到 Provider 时把 provider.sessionTtl 传给 SessionManager.updateSessionBindingSmart(...)
  • src/app/v1/_lib/proxy/response-handler.ts
    • Codex 场景:更新 prompt_cache_key 时传入 provider.sessionTtl
    • 在计费/统计完成后:通过 SessionManager.resolveSessionTtlForSession(sessionId) 获取 ttl,并调用 SessionTracker.refreshSession(..., ttlSeconds) 进行滑动续期。

管理后台 UI + i18n

  • src/app/[locale]/settings/providers/_components/forms/provider-form.tsx
    • 新增“Session TTL(秒)”输入框(可留空表示继承全局),并在提交前做 60~3600 校验。
  • messages/{en,ja,ru,zh-CN,zh-TW}/settings/providers/form/{sections,errors}.json
    • 新增字段文案与超范围提示。

测试

  • tests/unit/session-manager.test.ts:覆盖 SessionManager.resolveSessionTtl 的兜底与 clamp 行为。
  • tests/unit/settings/providers/model-multi-select-custom-models-ui.test.tsx:修复测试中误用未定义的 loadTestMessages(与本 PR 功能无关,但会导致单测失败)。

兼容性与默认行为

  • 对既有 Provider:session_ttl 默认为 NULL,行为不变(继续使用全局 SESSION_TTL 作为 session 绑定续期基准)。
  • 新增字段为可空、无默认值,不影响旧数据读写。

迁移与部署

  • 本 PR 包含 Drizzle migration:drizzle/0055_normal_johnny_storm.sql
  • 若启用 AUTO_MIGRATE=true:启动时自动应用;否则手动执行 bun run db:migrate

验证与测试

已在本地执行并通过:

  • bun run build
  • bun run lint(Checked 775 files,无错误)
  • bun run lint:fix(Checked 775 files,无可自动修复项)
  • bun run typecheck
  • bun run test(Test Files 137 passed (137),Tests 878 passed (878),Duration 42.79s)

风险与回滚

  • 风险:将 session_ttl 配得过长会增强 session 粘性、降低 provider 切换频率;已通过 60~3600 的范围限制避免极端配置。
  • 回滚:revert 本 PR;DB 新增字段可保留(不会影响旧逻辑)。如确有需要可再单独迁移删除 providers.session_ttl

@coderabbitai
Copy link

coderabbitai bot commented Jan 14, 2026

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

📝 Walkthrough

Walkthrough

在 providers 表新增可选整数列 session_ttl,并将该字段贯穿类型、验证、存储、UI 表单、会话管理与相关单元测试;同时更新 Drizzle 快照与迁移日记及多语言文本项。

Changes

内聚组 / 文件(s) 变更摘要
数据库模式与迁移
drizzle/0055_normal_johnny_storm.sql, drizzle/meta/0055_snapshot.json, drizzle/meta/_journal.json
增加 providers.session_ttl 整数列,更新快照与迁移日志 (idx 55)
本地化文本
messages/en/settings/providers/form/sections.json, messages/en/settings/providers/form/errors.json, messages/ja/.../sections.json, messages/ja/.../errors.json, messages/ru/.../sections.json, messages/ru/.../errors.json, messages/zh-CN/.../sections.json, messages/zh-CN/.../errors.json, messages/zh-TW/.../sections.json, messages/zh-TW/.../errors.json
新增 sessionTtl 字段描述/标签/占位符与 sessionTtlOutOfRange 验证错误,支持多语言;范围提示为 60–3600 秒
类型与 DB 模式声明
src/types/provider.ts, src/drizzle/schema.ts, src/lib/validation/schemas.ts
在 Provider/ProviderDisplay/Create/Update 类型中加入 sessionTtl/session_ttl;Drizzle schema 增加 session_ttl 列;Zod 验证 schema 增加带 60–3600 限制的 session_ttl 字段
后端存储层与转换
src/repository/provider.ts, src/repository/_shared/transformers.ts
在创建/查询/更新/批量优先级更新中读写并返回 session_ttl / sessionTtl 字段,transformer 将 DB 值映射为 number
动作层
src/actions/providers.ts
addProvider/editProvider 接受 `session_ttl?: number
表单 UI 与校验
src/app/[locale]/settings/providers/_components/forms/provider-form.tsx
新增 sessionTtlSeconds 状态、数值输入 UI(min=60,max=3600)、提交前校验并在创建/更新 payload 中包含 session_ttl
会话管理逻辑
src/lib/session-manager.ts, src/lib/session-tracker.ts
增加 TTL 解析工具 resolveSessionTtl / resolveSessionTtlForSession;使 bind/update/refresh 等方法可接受并使用 provider/session TTL,更新相关方法签名
代理/响应路径
src/app/v1/_lib/proxy/forwarder.ts, src/app/v1/_lib/proxy/response-handler.ts
调整 SessionManager 调用以传递 isFailoverSuccesssessionTtl;response 路径新增通过 resolveSessionTtlForSession 获取 TTL,并调整相关方法签名
单元测试
tests/unit/session-manager.test.ts, tests/unit/repository/provider.test.ts, tests/unit/lib/session-manager-helpers.test.ts, tests/unit/settings/providers/model-multi-select-custom-models-ui.test.tsx
新增 resolveSessionTtl 测试;扩展 provider repository 测试以覆盖 sessionTtl 投影;修正/统一测试导入路径与消息加载器;添加/调整断言以包含 sessionTtl

估计代码审查工作量

🎯 4 (复杂) | ⏱️ ~60 分钟

可能相关的问题

可能相关的 PRs

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 40.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed 标题清晰准确地总结了本次变更的核心内容——支持按供应商配置 Session TTL,并引用了相关 issue(#603)。
Description check ✅ Passed 描述详细全面,清楚阐述了变更目标、方案概述、具体变更点、测试验证、兼容性说明等,与代码变更内容保持高度一致。

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment


📜 Recent review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Cache: Disabled due to Reviews > Disable Cache setting

📥 Commits

Reviewing files that changed from the base of the PR and between 00136fe and 78f6294.

📒 Files selected for processing (1)
  • src/lib/session-tracker.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/lib/session-tracker.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: 🌐 API Tests
  • GitHub Check: Docker Build Test

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.


Comment @coderabbitai help to get the list of available commands and usage tips.

@gemini-code-assist
Copy link

Summary of Changes

Hello @YangQing-Lin, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

此拉取请求旨在通过引入供应商级别的 Session TTL 配置,提升系统在多供应商场景下的灵活性和可控性。此前,所有 Session 均使用统一的全局 TTL,限制了不同供应商对会话粘性或上下文缓存窗口的个性化需求。现在,系统能够根据每个供应商的特定设置来管理 Session 的生命周期,从而更好地适应各种业务场景,同时通过合理的范围限制避免极端配置带来的潜在风险。

Highlights

  • 供应商级 Session TTL 配置: 引入了在每个供应商(Provider)层面配置 Session TTL(会话存活时间)的功能,允许根据不同上游服务的需求,灵活设置会话粘性窗口,以优化命中率、稳定性或降低切换成本。
  • 数据库与模型更新: 在 providers 表中新增了 session_ttl 字段(整数类型,可空),并更新了 Drizzle 迁移文件和快照。相应的后端数据模型(ProviderProviderDisplayCreateProviderDataUpdateProviderData)也已更新以支持此新字段。
  • Session 管理逻辑增强: SessionManager 增加了 resolveSessionTtlresolveSessionTtlForSession 方法,用于根据供应商配置或全局默认值解析 Session TTL,并强制将 TTL 限制在 60 到 3600 秒之间。所有 Session 绑定和刷新操作现在都将使用此解析后的 TTL。
  • 代理层集成: 代理转发器(ProxyForwarder)和响应处理器(ProxyResponseHandler)已更新,确保在绑定 Session 到供应商或更新 Codex 缓存键时,能够正确传递和使用供应商配置的 sessionTtl
  • 管理后台 UI 与国际化: 管理后台的供应商表单中新增了“Session TTL(秒)”输入框,支持用户配置,并包含 60-3600 秒的范围校验。同时,相关的国际化(i18n)文本也已更新,覆盖了中、英、日、俄等语言的标签、描述和错误提示。
  • 测试覆盖与修复: 新增了 SessionManager.resolveSessionTtl 的单元测试,以验证其默认值和范围限制逻辑。此外,修复了一个与本 PR 功能无关但会导致单测失败的 model-multi-select-custom-models-ui.test.tsx 测试中的 loadTestMessages 调用问题。
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

这个 Pull Request 增加了一个很实用的功能,允许为每个供应商单独配置 Session TTL,提高了多供应商环境下的灵活性。代码实现非常全面,涵盖了数据库、后端逻辑、API 集成和前端 UI 的修改。代码结构清晰,并且为新逻辑编写了单元测试,值得称赞。

我的审查意见主要包含两点关于代码简化的建议,旨在移除冗余逻辑,以提高代码的可读性和可维护性。总的来说,这是一次高质量的贡献。

@github-actions github-actions bot added the size/XL Extra Large PR (> 1000 lines) label Jan 14, 2026
Copy link

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review Summary

No significant issues identified in this PR. The implementation of provider-specific Session TTL is well-structured, follows existing codebase patterns, and includes proper error handling with logging throughout.

PR Size: XL

  • Lines changed: 2835 (2775 additions, 60 deletions)
  • Files changed: 28

Note on PR size: This is an XL PR primarily due to the auto-generated Drizzle snapshot file (drizzle/meta/0055_snapshot.json ~2400 lines). The actual code changes are moderate and focused. Consider splitting future PRs if they involve multiple unrelated features.

Review Coverage

  • Logic and correctness - Clean
  • Security (OWASP Top 10) - Clean
  • Error handling - Clean (all error paths logged appropriately)
  • Type safety - Clean (proper nullable types, validation schema with 60-3600 range)
  • Documentation accuracy - Clean
  • Test coverage - Adequate (new tests for resolveSessionTtl covering fallback, clamping, and invalid global TTL)
  • Code clarity - Good (follows existing patterns)

Implementation Highlights

  • Database: New nullable session_ttl column added via proper Drizzle migration workflow
  • Validation: Schema enforces integer type with 60-3600 second range
  • TTL Resolution: resolveSessionTtl() properly handles null/undefined with global fallback and clamping
  • i18n: All 5 languages (en, ja, ru, zh-CN, zh-TW) have proper translations
  • Backward Compatibility: Existing providers with NULL session_ttl continue using global SESSION_TTL

Automated review by Claude AI

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
@greptile-apps
Copy link

greptile-apps bot commented Jan 16, 2026

Greptile encountered an error while reviewing this PR. Please reach out to support@greptile.com for assistance.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:i18n area:provider area:session enhancement New feature or request size/XL Extra Large PR (> 1000 lines)

Projects

Status: Backlog

Development

Successfully merging this pull request may close these issues.

1 participant