perf: batch gateway submits and isolate callbacks

This commit is contained in:
hectorzhao
2026-08-25 11:39:59 +08:00
parent c6f11014d6
commit 761c123b65
29 changed files with 1912 additions and 193 deletions
+5 -4
View File
@@ -32,7 +32,8 @@ func main() {
cmppAddr = ":17890"
}
apiBaseURL := os.Getenv("API_BASE_URL")
upstreamManager := &upstream.Manager{APIBaseURL: apiBaseURL}
callbackBaseURL := getenv("GATEWAY_CALLBACK_API_BASE_URL", apiBaseURL)
upstreamManager := &upstream.Manager{APIBaseURL: apiBaseURL, EventAPIBaseURL: callbackBaseURL}
var worker *submitworker.Worker
var resultOutbox *resultoutbox.Outbox
channelLimiter, err := ratelimit.New(os.Getenv("REDIS_URL"))
@@ -75,12 +76,12 @@ func main() {
worker.Group = getenv("GATEWAY_SUBMIT_GROUP", "cmpp-gateway")
worker.Consumer = getenv("GATEWAY_SUBMIT_CONSUMER", "gateway-1")
worker.Concurrency = positiveEnvInt("GATEWAY_SUBMIT_WORKER_CONCURRENCY", 64)
worker.APIBaseURL = apiBaseURL
worker.APIBaseURL = callbackBaseURL
resultOutbox = resultoutbox.New(worker.Redis)
resultOutbox.Stream = getenv("GATEWAY_SUBMIT_RESULT_STREAM", "gateway.submit.results")
resultOutbox.Group = getenv("GATEWAY_SUBMIT_RESULT_GROUP", "cmpp-api-callback")
resultOutbox.Consumer = getenv("GATEWAY_SUBMIT_RESULT_CONSUMER", "gateway-1")
resultOutbox.APIBaseURL = apiBaseURL
resultOutbox.APIBaseURL = callbackBaseURL
resultOutbox.Concurrency = positiveEnvInt("GATEWAY_SUBMIT_RESULT_WORKER_CONCURRENCY", 8)
worker.ResultOutbox = resultOutbox
upstreamManager.SubmitSegmentPublisher = resultOutbox
@@ -161,7 +162,7 @@ func main() {
return snapshot
}))
control.Register(mux, control.Server{
APIBaseURL: apiBaseURL,
APIBaseURL: callbackBaseURL,
Upstream: upstreamManager,
Limiter: channelLimiter,
Submit: func(ctx context.Context, command queue.SubmitCommand) (queue.SubmitResult, error) {
+6 -1
View File
@@ -23,6 +23,7 @@ const (
type Manager struct {
APIBaseURL string
EventAPIBaseURL string
HTTPClient *http.Client
SubmitSegmentPublisher SubmitSegmentPublisher
@@ -170,11 +171,15 @@ func (m *Manager) ConnectionCounts() (desired int, connected int) {
}
func (m *Manager) newConnectionPool(channelID string, connectionID string, config queue.UpstreamConfig) *connectionPool {
eventAPIBaseURL := m.EventAPIBaseURL
if eventAPIBaseURL == "" {
eventAPIBaseURL = m.APIBaseURL
}
return &connectionPool{
channelID: channelID,
connectionID: connectionID,
config: config,
apiBaseURL: m.APIBaseURL,
apiBaseURL: eventAPIBaseURL,
httpClient: m.HTTPClient,
reporter: func(ctx context.Context, state ConnectionState) error {
return m.post(ctx, "/admin/gateway/connections", state)
+11
View File
@@ -85,6 +85,17 @@ func TestNormalizeUpstreamConfigDefaults(t *testing.T) {
}
}
func TestManagerSeparatesConnectionStateAndSupplierEventAPIs(t *testing.T) {
manager := &Manager{APIBaseURL: "http://main-api/api", EventAPIBaseURL: "http://callback-api/api"}
pool := manager.newConnectionPool("channel-1", "channel-1:primary", queue.UpstreamConfig{DesiredConnections: 1})
if pool.apiBaseURL != manager.EventAPIBaseURL {
t.Fatalf("supplier events must use callback API, got %q", pool.apiBaseURL)
}
if manager.APIBaseURL == pool.apiBaseURL {
t.Fatal("connection-state control API must remain separate from supplier events")
}
}
func queueUpstreamConfigForTest() queue.UpstreamConfig {
return queue.UpstreamConfig{
GatewayHost: "127.0.0.1",