perf(worker): 以有界微批次提升准入吞吐
原因:线上 P24 同构验收中,单任务同步复制提交与全局容量锁串行化,使两个 Worker 的 48 个执行槽只能维持约 10–14 个运行任务,最老等待超过 15 分钟。 影响:新增可配置的 1–32 条准入微批次,默认 8;租约、任务准入与唯一 River job 在一个有界事务内原子提交,并按确定顺序预锁任务和容量范围,避免整窗 48 条大事务和多 Dispatcher 死锁。并容忍 rebind 已被其他 Dispatcher 完成的幂等竞态。 验证:Go 全量测试、go vet、真实 PostgreSQL 跨 Store 集成测试、ShellCheck、迁移安全检查、OpenAPI、前端 lint/test/build、Compose/Kubernetes 渲染及人工发布脚本均通过。
This commit is contained in:
@@ -31,6 +31,7 @@ func TestValidateIdentityFileSecretStoreRequiresDirectory(t *testing.T) {
|
||||
AsyncWorkerHardLimit: 2048,
|
||||
AsyncWorkerInstanceHardLimit: 32,
|
||||
AsyncWorkerRefreshIntervalSeconds: 5,
|
||||
AsyncAdmissionMicrobatchSize: 8,
|
||||
}
|
||||
if err := cfg.Validate(); err == nil || !strings.Contains(err.Error(), "IDENTITY_SECRET_DIR") {
|
||||
t.Fatalf("Validate() error = %v, want missing identity secret directory", err)
|
||||
@@ -48,6 +49,7 @@ func TestValidateIdentityKubernetesSecretStore(t *testing.T) {
|
||||
AsyncWorkerHardLimit: 2048,
|
||||
AsyncWorkerInstanceHardLimit: 32,
|
||||
AsyncWorkerRefreshIntervalSeconds: 5,
|
||||
AsyncAdmissionMicrobatchSize: 8,
|
||||
}
|
||||
if err := cfg.Validate(); err == nil || !strings.Contains(err.Error(), "namespace") {
|
||||
t.Fatalf("Validate() error = %v, want missing namespace", err)
|
||||
@@ -66,6 +68,7 @@ func TestValidateIdentitySecurityEventTiming(t *testing.T) {
|
||||
AsyncWorkerHardLimit: 2048,
|
||||
AsyncWorkerInstanceHardLimit: 32,
|
||||
AsyncWorkerRefreshIntervalSeconds: 5,
|
||||
AsyncAdmissionMicrobatchSize: 8,
|
||||
}
|
||||
if err := cfg.Validate(); err == nil || !strings.Contains(err.Error(), "heartbeat") {
|
||||
t.Fatalf("Validate() error = %v, want invalid stale threshold", err)
|
||||
@@ -77,6 +80,7 @@ func TestValidateAsyncWorkerSettings(t *testing.T) {
|
||||
AsyncWorkerHardLimit: 10001,
|
||||
AsyncWorkerInstanceHardLimit: 32,
|
||||
AsyncWorkerRefreshIntervalSeconds: 5,
|
||||
AsyncAdmissionMicrobatchSize: 8,
|
||||
}
|
||||
if err := cfg.Validate(); err == nil || !strings.Contains(err.Error(), "HARD_LIMIT") {
|
||||
t.Fatalf("Validate() error = %v, want invalid hard limit", err)
|
||||
@@ -102,6 +106,27 @@ func TestValidateAsyncWorkerSettings(t *testing.T) {
|
||||
if err := loaded.Validate(); err == nil || !strings.Contains(err.Error(), "INSTANCE_HARD_LIMIT") {
|
||||
t.Fatalf("Validate() error = %v, want invalid non-integer instance hard limit", err)
|
||||
}
|
||||
t.Setenv("AI_GATEWAY_ASYNC_WORKER_INSTANCE_HARD_LIMIT", "32")
|
||||
t.Setenv("AI_GATEWAY_ASYNC_ADMISSION_MICROBATCH_SIZE", "33")
|
||||
loaded = Load()
|
||||
if err := loaded.Validate(); err == nil || !strings.Contains(err.Error(), "MICROBATCH_SIZE") {
|
||||
t.Fatalf("Validate() error = %v, want invalid admission microbatch size", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoadAsyncAdmissionMicrobatchSize(t *testing.T) {
|
||||
cfg := Load()
|
||||
if cfg.AsyncAdmissionMicrobatchSize != 8 {
|
||||
t.Fatalf("admission microbatch size=%d, want 8", cfg.AsyncAdmissionMicrobatchSize)
|
||||
}
|
||||
t.Setenv("AI_GATEWAY_ASYNC_ADMISSION_MICROBATCH_SIZE", "4")
|
||||
cfg = Load()
|
||||
if err := cfg.Validate(); err != nil {
|
||||
t.Fatalf("valid admission microbatch size was rejected: %v", err)
|
||||
}
|
||||
if cfg.AsyncAdmissionMicrobatchSize != 4 {
|
||||
t.Fatalf("admission microbatch size=%d, want 4", cfg.AsyncAdmissionMicrobatchSize)
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoadAsyncQueueWorkerEnabled(t *testing.T) {
|
||||
|
||||
Reference in New Issue
Block a user