perf(cmpp): add durable inbound fast path

This commit is contained in:
hectorzhao
2026-08-20 17:34:45 +08:00
parent 26ef67fb6a
commit 0b63bcd74e
29 changed files with 1136 additions and 87 deletions
+11
View File
@@ -4,6 +4,7 @@ import (
"cmpp-platform/gateway/internal/metrics"
"context"
"crypto/md5"
"crypto/sha256"
"errors"
"fmt"
cmpp "github.com/bigwhite/gocmpp"
@@ -19,6 +20,7 @@ import (
// one internal message mapping per destination while CMPP receives one response.
type submitRequest struct {
RequestID string `json:"requestId,omitempty"`
Account string `json:"account"`
PhoneNumber string `json:"phoneNumber,omitempty"`
PhoneNumbers []string `json:"phoneNumbers,omitempty"`
@@ -117,6 +119,7 @@ func (s Server) handleSubmit(response *cmpp.Response, packet *cmpp.Packet, logge
releaseSubmitBarrier := beginDownstreamSubmitBarrier(packet.Conn)
apiStartedAt := time.Now()
result, err := s.submit(remote, submitRequest{
RequestID: inboundSubmitRequestID(session.connectionID, req.sequenceID, phones, content, req.srcID, longMessage),
Account: account,
PhoneNumber: phone,
PhoneNumbers: phones,
@@ -222,6 +225,14 @@ func (s Server) handleSubmit(response *cmpp.Response, packet *cmpp.Packet, logge
return false, nil
}
func inboundSubmitRequestID(connectionID string, sequenceID uint32, phones []string, content string, srcID string, longMessage *inboundLongMessageFragment) string {
// The key is stable for an API retry of the same packet but scoped to the authenticated
// connection, so a later client session may intentionally reuse the CMPP Sequence_Id.
payload := fmt.Sprintf("%s\x00%d\x00%s\x00%s\x00%s\x00%v", connectionID, sequenceID, strings.Join(phones, ","), strings.TrimSpace(srcID), content, longMessage)
digest := sha256.Sum256([]byte(payload))
return fmt.Sprintf("cmpp-inbound:%x", digest[:])
}
func observeInboundSubmitResponse(handlerStartedAt time.Time, responseReadyAt time.Time, accepted bool, next func(error)) func(error) {
return func(sendErr error) {
metrics.ObserveInboundStage("response_write", sendErr == nil, time.Since(responseReadyAt))