fix: close receipt delivery workflows
This commit is contained in:
@@ -174,6 +174,8 @@ type downstreamConnectionEvent struct {
|
||||
type downstreamSession struct {
|
||||
messageID string
|
||||
account string
|
||||
tenantID string
|
||||
applicationID string
|
||||
enterpriseCode string
|
||||
protocol string
|
||||
srcID string
|
||||
@@ -188,6 +190,7 @@ type downstreamSession struct {
|
||||
instanceID string
|
||||
report func(*downstreamSession, string, string)
|
||||
deliveryReport func(downstreamDeliveryLifecycleEvent)
|
||||
protocolLog func(protocolLogEvent)
|
||||
}
|
||||
|
||||
var downstreamRegistry = struct {
|
||||
@@ -244,6 +247,8 @@ func (s Server) handleLogin(response *cmpp.Response, packet *cmpp.Packet, logger
|
||||
now := time.Now().UTC()
|
||||
session := &downstreamSession{
|
||||
account: strings.TrimSpace(defaultString(auth.Account, account)),
|
||||
tenantID: strings.TrimSpace(auth.TenantID),
|
||||
applicationID: strings.TrimSpace(auth.ApplicationID),
|
||||
enterpriseCode: strings.TrimSpace(auth.EnterpriseCode),
|
||||
protocol: cmppVersionName(req.Version),
|
||||
srcID: strings.TrimSpace(auth.Account),
|
||||
@@ -256,6 +261,7 @@ func (s Server) handleLogin(response *cmpp.Response, packet *cmpp.Packet, logger
|
||||
instanceID: s.gatewayInstanceID(),
|
||||
report: s.reportConnection,
|
||||
deliveryReport: s.reportDownstreamDelivery,
|
||||
protocolLog: s.emitProtocolLog,
|
||||
}
|
||||
if !rememberAccount(session, auth.MaxConnections) {
|
||||
logger.Printf("cmpp inbound auth failed account=%s remote=%s err=connection limit exceeded max=%d", account, packet.Conn.Conn.RemoteAddr(), auth.MaxConnections)
|
||||
@@ -372,6 +378,8 @@ func (s Server) handleSubmit(response *cmpp.Response, packet *cmpp.Packet, logge
|
||||
rememberDownstream(downstreamSession{
|
||||
messageID: acceptedMessage.MessageID,
|
||||
account: account,
|
||||
tenantID: result.TenantID,
|
||||
applicationID: result.ApplicationID,
|
||||
enterpriseCode: session.enterpriseCode,
|
||||
protocol: clientProtocol,
|
||||
srcID: strings.TrimSpace(req.srcID),
|
||||
@@ -386,6 +394,7 @@ func (s Server) handleSubmit(response *cmpp.Response, packet *cmpp.Packet, logge
|
||||
instanceID: s.gatewayInstanceID(),
|
||||
report: session.report,
|
||||
deliveryReport: session.deliveryReport,
|
||||
protocolLog: session.protocolLog,
|
||||
})
|
||||
}
|
||||
if current := findSessionByConn(packet.Conn); current != nil && current.report != nil {
|
||||
@@ -1282,12 +1291,14 @@ func sendDownstream(session *downstreamSession, deliver cmpp.Packer, deliveryID
|
||||
tracker := registerDownstreamAck(session, deliveryID, sequenceID, messageID, ackDeadlineAt)
|
||||
if err := session.conn.SendPkt(deliver, sequenceID); err != nil {
|
||||
removeDownstreamAck(tracker)
|
||||
session.recordDownstreamProtocol(deliver, deliveryID, sequenceID, messageID, "failed", "SEND_FAILED", err)
|
||||
if session.report != nil {
|
||||
go session.report(session, "disconnected", err.Error())
|
||||
}
|
||||
forgetDownstream(session)
|
||||
return DownstreamSendResult{}, err
|
||||
}
|
||||
session.recordDownstreamProtocol(deliver, deliveryID, sequenceID, messageID, "success", "", nil)
|
||||
result := DownstreamSendResult{
|
||||
Sent: true, ConnectionID: session.connectionID,
|
||||
SequenceID: strconv.FormatUint(uint64(sequenceID), 10), MessageID: strconv.FormatUint(messageID, 10),
|
||||
@@ -1306,6 +1317,56 @@ func sendDownstream(session *downstreamSession, deliver cmpp.Packer, deliveryID
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (session *downstreamSession) recordDownstreamProtocol(
|
||||
deliver cmpp.Packer,
|
||||
deliveryID string,
|
||||
sequenceID uint32,
|
||||
messageID uint64,
|
||||
status string,
|
||||
resultCode string,
|
||||
sendErr error,
|
||||
) {
|
||||
if session == nil || session.protocolLog == nil {
|
||||
return
|
||||
}
|
||||
eventType, phone := downstreamDeliverMetadata(deliver)
|
||||
detail := map[string]any{"sequenceId": sequenceID, "deliveryId": deliveryID}
|
||||
if sendErr != nil {
|
||||
detail["error"] = sendErr.Error()
|
||||
}
|
||||
session.protocolLog(protocolLogEvent{
|
||||
Protocol: "cmpp",
|
||||
Direction: "platform_to_client",
|
||||
EventType: eventType,
|
||||
Status: status,
|
||||
TenantID: session.tenantID,
|
||||
ApplicationID: session.applicationID,
|
||||
Account: session.account,
|
||||
MessageID: session.messageID,
|
||||
GatewayMessageID: strconv.FormatUint(messageID, 10),
|
||||
Phone: defaultString(phone, session.phoneNumber),
|
||||
ResultCode: resultCode,
|
||||
Detail: detail,
|
||||
})
|
||||
}
|
||||
|
||||
func downstreamDeliverMetadata(deliver cmpp.Packer) (string, string) {
|
||||
switch packet := deliver.(type) {
|
||||
case *cmpp.Cmpp2DeliverReqPkt:
|
||||
if packet.RegisterDelivery == 1 {
|
||||
return "deliver_receipt", packet.SrcTerminalId
|
||||
}
|
||||
return "deliver_uplink", packet.SrcTerminalId
|
||||
case *cmpp.Cmpp3DeliverReqPkt:
|
||||
if packet.RegisterDelivery == 1 {
|
||||
return "deliver_receipt", packet.SrcTerminalId
|
||||
}
|
||||
return "deliver_uplink", packet.SrcTerminalId
|
||||
default:
|
||||
return "deliver", ""
|
||||
}
|
||||
}
|
||||
|
||||
func downstreamDeliverMessageID(deliver cmpp.Packer) uint64 {
|
||||
switch packet := deliver.(type) {
|
||||
case *cmpp.Cmpp2DeliverReqPkt:
|
||||
@@ -1389,6 +1450,26 @@ func handleDownstreamAcknowledgement(conn *cmpp.Conn, sequenceID uint32, message
|
||||
SequenceID: sequenceID, MessageID: messageID, Result: result, ObservedAt: time.Now().UTC(),
|
||||
})
|
||||
}
|
||||
if tracker.session != nil && tracker.session.protocolLog != nil {
|
||||
status := "success"
|
||||
if result != 0 {
|
||||
status = "failed"
|
||||
}
|
||||
tracker.session.protocolLog(protocolLogEvent{
|
||||
Protocol: "cmpp",
|
||||
Direction: "client_to_platform",
|
||||
EventType: "deliver_resp",
|
||||
Status: status,
|
||||
TenantID: tracker.session.tenantID,
|
||||
ApplicationID: tracker.session.applicationID,
|
||||
Account: tracker.session.account,
|
||||
MessageID: tracker.session.messageID,
|
||||
GatewayMessageID: strconv.FormatUint(messageID, 10),
|
||||
Phone: tracker.session.phoneNumber,
|
||||
ResultCode: strconv.FormatUint(uint64(result), 10),
|
||||
Detail: map[string]any{"sequenceId": sequenceID, "deliveryId": tracker.deliveryID},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func downstreamAckTimeout() time.Duration {
|
||||
|
||||
Reference in New Issue
Block a user