perf(cmpp): decouple supplier result callbacks
This commit is contained in:
@@ -7,7 +7,6 @@ import (
|
||||
"fmt"
|
||||
cmpp "github.com/bigwhite/gocmpp"
|
||||
cmpputils "github.com/bigwhite/gocmpp/utils"
|
||||
"log"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
@@ -17,58 +16,30 @@ import (
|
||||
|
||||
func (m *Manager) Submit(ctx context.Context, cmd queue.SubmitCommand) (queue.SubmitResult, error) {
|
||||
if err := validateSubmitCommand(cmd); err != nil {
|
||||
result := submitResult(cmd, 0, "", "rejected", "INVALID_COMMAND", err.Error())
|
||||
if postErr := m.postSubmitCallback(ctx, "/gateway/events/submit-result", result); postErr != nil {
|
||||
return result, postErr
|
||||
}
|
||||
return result, err
|
||||
return submitResult(cmd, 0, "", "rejected", "INVALID_COMMAND", err.Error()), err
|
||||
}
|
||||
|
||||
pool, err := m.connectionFor(cmd)
|
||||
if err != nil {
|
||||
result := submitResult(cmd, 0, "", "rejected", "CONNECT_FAILED", err.Error())
|
||||
if postErr := m.postSubmitCallback(ctx, "/gateway/events/submit-result", result); postErr != nil {
|
||||
return result, postErr
|
||||
}
|
||||
return result, err
|
||||
return submitResult(cmd, 0, "", "rejected", "CONNECT_FAILED", err.Error()), err
|
||||
}
|
||||
|
||||
result, err := pool.submit(ctx, cmd, func(segment queue.SubmitSegmentResult) {
|
||||
payload := struct {
|
||||
queue.Envelope
|
||||
SubmitID string `json:"submitId,omitempty"`
|
||||
queue.SubmitSegmentResult
|
||||
}{
|
||||
Envelope: cmd.Envelope,
|
||||
SubmitID: cmd.SubmitID,
|
||||
SubmitSegmentResult: segment,
|
||||
}
|
||||
callbackCtx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
|
||||
postErr := m.postSubmitCallback(callbackCtx, "/gateway/events/submit-segment-result", payload)
|
||||
cancel()
|
||||
if postErr != nil {
|
||||
log.Printf(
|
||||
"protocol_event protocol=cmpp direction=gateway_to_api event=submit_segment_result status=forward_failed channel_id=%s message_id=%s segment=%d/%d error=%q",
|
||||
cmd.ChannelID, cmd.MessageID, segment.SegmentIndex, segment.SegmentTotal, postErr,
|
||||
)
|
||||
result, err := pool.submit(ctx, cmd, func(segment queue.SubmitSegmentResult) error {
|
||||
if m.SubmitSegmentPublisher == nil {
|
||||
return fmt.Errorf("submit segment result publisher is required")
|
||||
}
|
||||
// A segment result must reach durable local storage before the next segment.
|
||||
// This cannot make the supplier/Redis boundary globally atomic, but it avoids
|
||||
// holding the supplier slot for an API round trip and minimizes untracked sends.
|
||||
return m.SubmitSegmentPublisher.PublishSubmitSegment(ctx, cmd, segment)
|
||||
})
|
||||
if err != nil {
|
||||
if postErr := m.postSubmitCallback(ctx, "/gateway/events/submit-result", result); postErr != nil {
|
||||
return result, postErr
|
||||
}
|
||||
return result, err
|
||||
}
|
||||
if err := m.postSubmitCallback(ctx, "/gateway/events/submit-result", result); err != nil {
|
||||
return result, err
|
||||
}
|
||||
return result, nil
|
||||
return result, err
|
||||
}
|
||||
|
||||
func (p *connectionPool) submit(
|
||||
ctx context.Context,
|
||||
cmd queue.SubmitCommand,
|
||||
onSegment func(queue.SubmitSegmentResult),
|
||||
onSegment func(queue.SubmitSegmentResult) error,
|
||||
) (queue.SubmitResult, error) {
|
||||
parts, err := splitSubmitContent(cmd.CMPP.MsgFmt, cmd.Content)
|
||||
if err != nil {
|
||||
@@ -95,7 +66,10 @@ func (p *connectionPool) submit(
|
||||
segment := submitSegmentResult(part, seq, gatewayMessageID, result)
|
||||
segments = append(segments, segment)
|
||||
if onSegment != nil {
|
||||
onSegment(segment)
|
||||
if publishErr := onSegment(segment); publishErr != nil {
|
||||
result.Segments = segments
|
||||
return result, publishErr
|
||||
}
|
||||
}
|
||||
if firstSequence == 0 {
|
||||
firstSequence = seq
|
||||
@@ -118,13 +92,6 @@ func (p *connectionPool) submit(
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (m *Manager) postSubmitCallback(ctx context.Context, path string, payload any) error {
|
||||
startedAt := time.Now()
|
||||
err := m.post(ctx, path, payload)
|
||||
metrics.ObserveSubmitStage("api_callback", err == nil, time.Since(startedAt))
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *connection) submitPart(ctx context.Context, cmd queue.SubmitCommand, part submitPart) (uint32, string, queue.SubmitResult, error) {
|
||||
rspCh := make(chan submitPartResponse, 1)
|
||||
pkt := c.submitRequestPacket(cmd, part)
|
||||
|
||||
Reference in New Issue
Block a user