解耦 Tiantoken 与 VectorEngine 的图片请求超时
- AppConfig 新增 tiantoken_image_request_timeout_ms(默认 1000000),env 只读 TIANTOKEN_IMAGE_REQUEST_TIMEOUT_MS - VECTOR_ENGINE_IMAGE_REQUEST_TIMEOUT_MS 只写 vector_engine_image_request_timeout_ms,不再被 Tiantoken 变量覆盖 - Tiantoken 图片 client 与 OpenAiImageSettings.request_timeout_ms 改用新字段,两个 provider 各用自己的超时 - config 测试补 Tiantoken / VectorEngine 双向不覆盖断言,deploy env 示例补 VECTOR_ENGINE_IMAGE_REQUEST_TIMEOUT_MS=1000000 - 同步开发运维文档与 decision-log
This commit is contained in:
@@ -18,6 +18,7 @@ const DEFAULT_EXTERNAL_GENERATION_WORKER_LEASE_SECONDS: u64 = 600;
|
||||
const DEFAULT_EXTERNAL_GENERATION_WORKER_JOB_TIMEOUT_SECONDS: u64 = 900;
|
||||
const DEFAULT_EXTERNAL_GENERATION_WORKER_LONG_JOB_TIMEOUT_SECONDS: u64 = 1_800;
|
||||
pub(crate) const DEFAULT_VECTOR_ENGINE_IMAGE_REQUEST_TIMEOUT_MS: u64 = 1_000_000;
|
||||
pub(crate) const DEFAULT_TIANTOKEN_IMAGE_REQUEST_TIMEOUT_MS: u64 = 1_000_000;
|
||||
pub(crate) const DEFAULT_ELEVENLABS_REQUEST_TIMEOUT_MS: u64 = 180_000;
|
||||
const DEFAULT_EDITOR_BGFILTER_BASE_URL: &str = "http://58.87.105.82/bgfilter";
|
||||
const DEFAULT_EDITOR_BGFILTER_SINGLE_IMAGE_ESTIMATE_MS: u64 = 5_000;
|
||||
@@ -225,6 +226,12 @@ pub struct AppConfig {
|
||||
/// 启动时落到 `AppConfig` 字段,使 `AppState` 构造与测试构造复用同一条路径。
|
||||
pub tiantoken_base_url: String,
|
||||
pub tiantoken_api_key: Option<String>,
|
||||
/// Tiantoken 图片链路(GPT Image 2.5 生成 / 编辑)的单次 attempt 超时。
|
||||
///
|
||||
/// 与 `vector_engine_image_request_timeout_ms` 相互独立,只由
|
||||
/// `TIANTOKEN_IMAGE_REQUEST_TIMEOUT_MS` 配置,避免一个 provider 的超时设置
|
||||
/// 顺带改写另一个 provider 的 deadline。
|
||||
pub tiantoken_image_request_timeout_ms: u64,
|
||||
pub elevenlabs_base_url: String,
|
||||
pub elevenlabs_api_key: Option<String>,
|
||||
pub elevenlabs_request_timeout_ms: u64,
|
||||
@@ -541,6 +548,7 @@ impl Default for AppConfig {
|
||||
vector_engine_audio_request_timeout_ms: 180_000,
|
||||
tiantoken_base_url: String::new(),
|
||||
tiantoken_api_key: None,
|
||||
tiantoken_image_request_timeout_ms: DEFAULT_TIANTOKEN_IMAGE_REQUEST_TIMEOUT_MS,
|
||||
elevenlabs_base_url: String::new(),
|
||||
elevenlabs_api_key: None,
|
||||
elevenlabs_request_timeout_ms: DEFAULT_ELEVENLABS_REQUEST_TIMEOUT_MS,
|
||||
@@ -1338,18 +1346,25 @@ impl AppConfig {
|
||||
|
||||
config.vector_engine_api_key = read_first_non_empty_env(&["VECTOR_ENGINE_API_KEY"]);
|
||||
|
||||
if let Some(vector_engine_image_request_timeout_ms) =
|
||||
read_first_positive_u64_env(&["VECTOR_ENGINE_IMAGE_REQUEST_TIMEOUT_MS"])
|
||||
{
|
||||
// 单次 attempt 上限允许按环境收短;worker 调用还会受整次任务的绝对 deadline 约束。
|
||||
config.vector_engine_image_request_timeout_ms = vector_engine_image_request_timeout_ms;
|
||||
}
|
||||
|
||||
// Tiantoken 只读取自己的环境变量,不从 VectorEngine 配置回退;启动时冻结进 AppConfig,
|
||||
// 供 AppState 构造编辑器 LLM / 图片 client 时复用同一条配置路径。
|
||||
config.tiantoken_base_url =
|
||||
read_first_non_empty_env(&["TIANTOKEN_BASE_URL"]).unwrap_or_default();
|
||||
config.tiantoken_api_key = read_first_non_empty_env(&["TIANTOKEN_API_KEY"]);
|
||||
|
||||
if let Some(tiantoken_image_request_timeout_ms) = read_first_positive_u64_env(&[
|
||||
"TIANTOKEN_IMAGE_REQUEST_TIMEOUT_MS",
|
||||
"VECTOR_ENGINE_IMAGE_REQUEST_TIMEOUT_MS",
|
||||
]) {
|
||||
// 单次 attempt 上限允许按环境收短;worker 调用还会受整次任务的绝对 deadline 约束。
|
||||
config.vector_engine_image_request_timeout_ms = tiantoken_image_request_timeout_ms;
|
||||
if let Some(tiantoken_image_request_timeout_ms) =
|
||||
read_first_positive_u64_env(&["TIANTOKEN_IMAGE_REQUEST_TIMEOUT_MS"])
|
||||
{
|
||||
// Tiantoken 图片链路独立计时:`TIANTOKEN_IMAGE_REQUEST_TIMEOUT_MS` 不再改写
|
||||
// VectorEngine 的图片超时,两个 provider 各用自己的配置与默认值。
|
||||
config.tiantoken_image_request_timeout_ms = tiantoken_image_request_timeout_ms;
|
||||
}
|
||||
|
||||
if let Some(vector_engine_audio_request_timeout_ms) =
|
||||
@@ -2288,6 +2303,7 @@ mod tests {
|
||||
std::env::remove_var("VECTOR_ENGINE_BASE_URL");
|
||||
std::env::remove_var("VECTOR_ENGINE_API_KEY");
|
||||
std::env::remove_var("VECTOR_ENGINE_IMAGE_REQUEST_TIMEOUT_MS");
|
||||
std::env::remove_var("TIANTOKEN_IMAGE_REQUEST_TIMEOUT_MS");
|
||||
std::env::remove_var("HYPER3D_BASE_URL");
|
||||
std::env::remove_var("DASHSCOPE_SCENE_IMAGE_MODEL");
|
||||
std::env::remove_var("DASHSCOPE_REFERENCE_IMAGE_MODEL");
|
||||
@@ -2306,6 +2322,7 @@ mod tests {
|
||||
std::env::set_var("VECTOR_ENGINE_BASE_URL", "https://vector.internal.example");
|
||||
std::env::set_var("VECTOR_ENGINE_API_KEY", "vector-engine-key");
|
||||
std::env::set_var("VECTOR_ENGINE_IMAGE_REQUEST_TIMEOUT_MS", "210000");
|
||||
std::env::set_var("TIANTOKEN_IMAGE_REQUEST_TIMEOUT_MS", "180000");
|
||||
std::env::set_var("HYPER3D_BASE_URL", "https://model.internal.example/api/v2");
|
||||
std::env::set_var("DASHSCOPE_SCENE_IMAGE_MODEL", "scene-model");
|
||||
std::env::set_var("DASHSCOPE_REFERENCE_IMAGE_MODEL", "reference-model");
|
||||
@@ -2332,6 +2349,8 @@ mod tests {
|
||||
"https://vector.internal.example"
|
||||
);
|
||||
assert_eq!(config.vector_engine_image_request_timeout_ms, 210_000);
|
||||
// 两个 provider 的图片超时互不覆盖:Tiantoken 用 TIANTOKEN_*,VectorEngine 用 VECTOR_ENGINE_*。
|
||||
assert_eq!(config.tiantoken_image_request_timeout_ms, 180_000);
|
||||
assert_eq!(
|
||||
config.hyper3d_base_url,
|
||||
"https://model.internal.example/api/v2"
|
||||
@@ -2357,6 +2376,7 @@ mod tests {
|
||||
std::env::remove_var("VECTOR_ENGINE_BASE_URL");
|
||||
std::env::remove_var("VECTOR_ENGINE_API_KEY");
|
||||
std::env::remove_var("VECTOR_ENGINE_IMAGE_REQUEST_TIMEOUT_MS");
|
||||
std::env::remove_var("TIANTOKEN_IMAGE_REQUEST_TIMEOUT_MS");
|
||||
std::env::remove_var("HYPER3D_BASE_URL");
|
||||
std::env::remove_var("DASHSCOPE_SCENE_IMAGE_MODEL");
|
||||
std::env::remove_var("DASHSCOPE_REFERENCE_IMAGE_MODEL");
|
||||
|
||||
@@ -108,7 +108,7 @@ pub(crate) fn require_openai_image_settings(
|
||||
Ok(OpenAiImageSettings {
|
||||
base_url: base_url.to_string(),
|
||||
api_key: api_key.to_string(),
|
||||
request_timeout_ms: state.config.vector_engine_image_request_timeout_ms.max(1),
|
||||
request_timeout_ms: state.config.tiantoken_image_request_timeout_ms.max(1),
|
||||
request_deadline: None,
|
||||
external_api_audit_state: Some(state.clone()),
|
||||
external_api_audit_user_id: None,
|
||||
|
||||
@@ -645,7 +645,7 @@ impl AppState {
|
||||
ImageProvider::Tiantoken,
|
||||
tiantoken_base_url.clone(),
|
||||
tiantoken_api_key.clone(),
|
||||
config.vector_engine_image_request_timeout_ms,
|
||||
config.tiantoken_image_request_timeout_ms,
|
||||
)?;
|
||||
let llm_client = build_llm_client(&config)?;
|
||||
let vector_engine_llm_client = build_vector_engine_llm_client(
|
||||
|
||||
Reference in New Issue
Block a user