fix(media): 统一图片结果 URL 化并限制同步 Base64
将上游 URL 直接持久化,内联媒体经对象存储后仅保留 URL 与内部定位元数据;异步轮询、任务详情和幂等重放统一使用零对象读取的 URL 投影,并增加 64KiB 响应门禁。 OpenAI 图片接口接受 url 与 b64_json,同步 Base64 限制为 20MiB 和每 Pod 2 并发;新增历史结果迁移清零门禁、结果指标和 API GOMEMLIMIT。 验证:API go test ./...、go vet、聚焦 race、pnpm openapi、pnpm lint/test/build、迁移安全检查与 docker compose config 均通过。
This commit is contained in:
@@ -109,6 +109,11 @@ type Metrics struct {
|
||||
storageChannelFailovers atomic.Uint64
|
||||
storageAllChannelsFailed atomic.Uint64
|
||||
storageObjectifiedBytes atomic.Uint64
|
||||
resultSourceUpstreamURL atomic.Uint64
|
||||
resultSourceUploaded atomic.Uint64
|
||||
resultPollResponses atomic.Uint64
|
||||
resultPollResponseBytes atomic.Uint64
|
||||
resultPollOversized atomic.Uint64
|
||||
taskAdmissionWaitBuckets [11]atomic.Uint64
|
||||
taskAdmissionWaitMicros atomic.Uint64
|
||||
}
|
||||
@@ -345,6 +350,27 @@ func (m *Metrics) ObserveObjectStorage(event string, provider string, bytes int6
|
||||
}
|
||||
}
|
||||
|
||||
func (m *Metrics) ObserveResultStorage(source string) {
|
||||
switch strings.ToLower(strings.TrimSpace(source)) {
|
||||
case "upstream_url":
|
||||
m.resultSourceUpstreamURL.Add(1)
|
||||
case "uploaded":
|
||||
m.resultSourceUploaded.Add(1)
|
||||
}
|
||||
}
|
||||
|
||||
func (m *Metrics) ObserveResultDelivery(event string, bytes int64) {
|
||||
switch strings.ToLower(strings.TrimSpace(event)) {
|
||||
case "poll_success":
|
||||
m.resultPollResponses.Add(1)
|
||||
if bytes > 0 {
|
||||
m.resultPollResponseBytes.Add(uint64(bytes))
|
||||
}
|
||||
case "poll_oversized":
|
||||
m.resultPollOversized.Add(1)
|
||||
}
|
||||
}
|
||||
|
||||
func (m *Metrics) ObserveTaskAdmissionWait(wait time.Duration) {
|
||||
if wait < 0 {
|
||||
wait = 0
|
||||
@@ -561,6 +587,13 @@ func (m *Metrics) Handler(provider MetricsSnapshotProvider, issuer, audience str
|
||||
plainCounter(w, "easyai_gateway_storage_channel_failovers_total", "Switches to the next configured storage channel.", m.storageChannelFailovers.Load())
|
||||
plainCounter(w, "easyai_gateway_storage_all_channels_failed_total", "Storage writes where every eligible channel failed.", m.storageAllChannelsFailed.Load())
|
||||
plainCounter(w, "easyai_gateway_storage_objectified_bytes_total", "Binary bytes successfully written through storage channels.", m.storageObjectifiedBytes.Load())
|
||||
outcomeCounters(w, "easyai_gateway_result_storage_total", "Generated media results by canonical storage source.", []outcomeValue{
|
||||
{"upstream_url", m.resultSourceUpstreamURL.Load()},
|
||||
{"uploaded", m.resultSourceUploaded.Load()},
|
||||
})
|
||||
plainCounter(w, "easyai_gateway_result_poll_responses_total", "Successful URL-only task result responses.", m.resultPollResponses.Load())
|
||||
plainCounter(w, "easyai_gateway_result_poll_response_bytes_total", "Bytes written by successful URL-only task result responses.", m.resultPollResponseBytes.Load())
|
||||
plainCounter(w, "easyai_gateway_result_poll_oversized_total", "Task result responses rejected by the URL-only size gate.", m.resultPollOversized.Load())
|
||||
publicErrorCounters(w, publicerror.MetricSnapshot())
|
||||
platformModelRateLimitUtilizationGauges(w, modelRateLimits)
|
||||
plainGauge(w, "easyai_gateway_postgres_pool_max_connections", "Maximum PostgreSQL connections in this process pool.", int64(postgresPool.MaxConnections))
|
||||
|
||||
Reference in New Issue
Block a user