新增 UMQ (User Message Queue) 双模式支持: - serialize: 账号级分布式串行锁 + RPM 自适应延迟(严格限流) - throttle: 仅 RPM 自适应前置延迟,不阻塞并发(软性限速) 后端: - config: 新增 Mode 字段,保留 Enabled 向后兼容 - service: 新增 UserMessageQueueService(Lua 锁/延迟算法/清理 worker) - repository: 新增 UserMsgQueueCache(Redis Lua acquire/release/force-release) - handler: 新增 UserMsgQueueHelper(SSE ping + 等待循环 + throttle) - gateway: 按 mode 分支集成 serialize/throttle 逻辑 - lint: 修复 gofmt rewrite rules、errcheck 类型断言、staticcheck QF1012 前端: - 三态选择器 UI(关闭/软性限速/串行队列)替代 toggle 开关 - BulkEdit 支持 null 语义(不修改) - i18n 中英文文案 通过 6 轮专家评审(42 次 review)、golangci-lint、单元测试、集成测试。
65 lines
1.4 KiB
Go
65 lines
1.4 KiB
Go
package repository
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
)
|
|
|
|
type latencyHistogramBucket struct {
|
|
upperMs int
|
|
label string
|
|
}
|
|
|
|
var latencyHistogramBuckets = []latencyHistogramBucket{
|
|
{upperMs: 100, label: "0-100ms"},
|
|
{upperMs: 200, label: "100-200ms"},
|
|
{upperMs: 500, label: "200-500ms"},
|
|
{upperMs: 1000, label: "500-1000ms"},
|
|
{upperMs: 2000, label: "1000-2000ms"},
|
|
{upperMs: 0, label: "2000ms+"}, // default bucket
|
|
}
|
|
|
|
var latencyHistogramOrderedRanges = func() []string {
|
|
out := make([]string, 0, len(latencyHistogramBuckets))
|
|
for _, b := range latencyHistogramBuckets {
|
|
out = append(out, b.label)
|
|
}
|
|
return out
|
|
}()
|
|
|
|
func latencyHistogramRangeCaseExpr(column string) string {
|
|
var sb strings.Builder
|
|
_, _ = sb.WriteString("CASE\n")
|
|
|
|
for _, b := range latencyHistogramBuckets {
|
|
if b.upperMs <= 0 {
|
|
continue
|
|
}
|
|
fmt.Fprintf(&sb, "\tWHEN %s < %d THEN '%s'\n", column, b.upperMs, b.label)
|
|
}
|
|
|
|
// Default bucket.
|
|
last := latencyHistogramBuckets[len(latencyHistogramBuckets)-1]
|
|
fmt.Fprintf(&sb, "\tELSE '%s'\n", last.label)
|
|
_, _ = sb.WriteString("END")
|
|
return sb.String()
|
|
}
|
|
|
|
func latencyHistogramRangeOrderCaseExpr(column string) string {
|
|
var sb strings.Builder
|
|
_, _ = sb.WriteString("CASE\n")
|
|
|
|
order := 1
|
|
for _, b := range latencyHistogramBuckets {
|
|
if b.upperMs <= 0 {
|
|
continue
|
|
}
|
|
fmt.Fprintf(&sb, "\tWHEN %s < %d THEN %d\n", column, b.upperMs, order)
|
|
order++
|
|
}
|
|
|
|
fmt.Fprintf(&sb, "\tELSE %d\n", order)
|
|
_, _ = sb.WriteString("END")
|
|
return sb.String()
|
|
}
|