feat(queue): 增加非文本模型分布式准入队列
使用 PostgreSQL 统一同步与异步非文本任务的并发准入、持久化等待和 Worker 容量分配,并将生产 API 与独立 Worker 角色拆分。 补充策略管理、共享契约、OpenAPI、Kubernetes 双节点 Worker 清单及跨节点验收脚本;未默认启用任何生产 queue_size 策略。 已在原基线完成 Go、前端、迁移、Shell、Kustomize 与长任务容量验收;合入最新主干后将重新执行发布门禁。
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import type { BaseModelCatalogItem } from '@easyai-ai-gateway/contracts';
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import { createEmptyPlatformForm, platformModelPayloads } from './platform-form';
|
||||
import { createEmptyPlatformForm, platformModelPayloads, platformPayload, validatePlatformForm } from './platform-form';
|
||||
|
||||
const baseModel = {
|
||||
id: 'model-1',
|
||||
@@ -53,4 +53,78 @@ describe('platform model rate limit payload', () => {
|
||||
expect(payload.rateLimitPolicyMode).toBe('override');
|
||||
expect(payload.rateLimitPolicy).toEqual({ rules: [] });
|
||||
});
|
||||
|
||||
it('serializes queue length and defaults maximum wait to 600 seconds', () => {
|
||||
const form = {
|
||||
...selectedForm(),
|
||||
name: 'Queue platform',
|
||||
baseUrl: 'https://example.test',
|
||||
testMode: true,
|
||||
queueSize: '12',
|
||||
queueMaxWaitSeconds: '',
|
||||
modelOverrideRateLimit: true,
|
||||
modelRateLimitOverrideTouched: true,
|
||||
modelQueueSize: '4',
|
||||
modelQueueMaxWaitSeconds: '90',
|
||||
};
|
||||
|
||||
expect(platformPayload(form).rateLimitPolicy).toEqual({
|
||||
rules: [{ metric: 'queue_size', limit: 12, maxWaitSeconds: 600 }],
|
||||
});
|
||||
expect(platformModelPayloads([baseModel], form)[0].rateLimitPolicy).toEqual({
|
||||
rules: [{ metric: 'queue_size', limit: 4, maxWaitSeconds: 90 }],
|
||||
});
|
||||
});
|
||||
|
||||
it('rejects queue values outside the shared policy bounds', () => {
|
||||
const form = {
|
||||
...selectedForm(),
|
||||
name: 'Queue platform',
|
||||
baseUrl: 'https://example.test',
|
||||
testMode: true,
|
||||
queueSize: '10001',
|
||||
};
|
||||
expect(validatePlatformForm(form, 1)).toContain('1–10000');
|
||||
expect(validatePlatformForm({ ...form, queueSize: '2', queueMaxWaitSeconds: '3601' }, 1)).toContain('1–3600');
|
||||
});
|
||||
|
||||
it('preserves unknown policy fields and non-editable rules', () => {
|
||||
const form = {
|
||||
...selectedForm(),
|
||||
name: 'Compatible platform',
|
||||
baseUrl: 'https://example.test',
|
||||
testMode: true,
|
||||
concurrencyLimit: '3',
|
||||
queueSize: '6',
|
||||
rateLimitPolicyExtra: { extensionMode: 'legacy' },
|
||||
rateLimitRuleExtras: {
|
||||
concurrent: { consume: 'lease', vendorHint: 'keep' },
|
||||
queue_size: { vendorQueueMode: 'shared' },
|
||||
},
|
||||
rateLimitPreservedRules: [
|
||||
{ metric: 'tpm_input', limit: 1234, vendorWindow: true },
|
||||
],
|
||||
};
|
||||
|
||||
expect(platformPayload(form).rateLimitPolicy).toEqual({
|
||||
extensionMode: 'legacy',
|
||||
rules: [
|
||||
{ metric: 'tpm_input', limit: 1234, vendorWindow: true },
|
||||
{
|
||||
consume: 'lease',
|
||||
vendorHint: 'keep',
|
||||
metric: 'concurrent',
|
||||
limit: 3,
|
||||
windowSeconds: 60,
|
||||
leaseTtlSeconds: 120,
|
||||
},
|
||||
{
|
||||
vendorQueueMode: 'shared',
|
||||
metric: 'queue_size',
|
||||
limit: 6,
|
||||
maxWaitSeconds: 600,
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user