fix: 作废投递走统一终态函数并写回执收尾
This commit is contained in:
@@ -8,6 +8,9 @@ import (
|
||||
"git.asio.asia/nixevol/NixMsg/internal/protocol"
|
||||
)
|
||||
|
||||
// DefaultVoidRetentionDays 是 group/identity 作废路径未接线配置时的记录保留天数。
|
||||
const DefaultVoidRetentionDays = 7
|
||||
|
||||
// 投递状态(DEVELOPMENT 7.1)。
|
||||
const (
|
||||
DeliveryPending = "pending"
|
||||
@@ -116,7 +119,7 @@ WHERE gm.group_id = ? AND gm.endpoint_id != ?`, destID, senderID)
|
||||
}
|
||||
|
||||
if completeEarly {
|
||||
if err := finalizeMessageTx(tx, seq, wantReceipt, senderID, "", msgReason, nowMs, a.lim.RecordRetentionDays); err != nil {
|
||||
if err := FinalizeMessageTx(tx, seq, wantReceipt, senderID, "", msgReason, nowMs, a.lim.RecordRetentionDays); err != nil {
|
||||
return "", true, err
|
||||
}
|
||||
return StateCompleted, true, nil
|
||||
@@ -192,7 +195,7 @@ VALUES(?,?,?,?,?,?,?,NULL,NULL,0,?)`,
|
||||
}
|
||||
return StateDispatched, true, nil
|
||||
}
|
||||
if err := finalizeMessageTx(tx, seq, wantReceipt, senderID, "", "", nowMs, a.lim.RecordRetentionDays); err != nil {
|
||||
if err := FinalizeMessageTx(tx, seq, wantReceipt, senderID, "", "", nowMs, a.lim.RecordRetentionDays); err != nil {
|
||||
return "", true, err
|
||||
}
|
||||
return StateCompleted, true, nil
|
||||
@@ -212,9 +215,9 @@ func (a *App) lookupConn(endpointID string) (LiveConn, bool) {
|
||||
return a.conns.Current(endpointID)
|
||||
}
|
||||
|
||||
// finalizeMessageTx 无 pending 时收尾:completed、删正文;记录天数 0 则删消息与投递。
|
||||
// FinalizeMessageTx 无 pending 时收尾:completed、删正文;记录天数 0 则删消息与投递。
|
||||
// msgReason 非空时写入消息 reason(发送前结束);endpointID 为空表示消息级回执。
|
||||
func finalizeMessageTx(tx *sql.Tx, seq int64, wantReceipt bool, senderID, endpointID, msgReason string, nowMs int64, recordDays int) error {
|
||||
func FinalizeMessageTx(tx *sql.Tx, seq int64, wantReceipt bool, senderID, endpointID, msgReason string, nowMs int64, recordDays int) error {
|
||||
var msgID string
|
||||
var receipt int
|
||||
if err := tx.QueryRow(`SELECT id, receipt FROM messages WHERE seq = ?`, seq).Scan(&msgID, &receipt); err != nil {
|
||||
@@ -244,8 +247,8 @@ func finalizeMessageTx(tx *sql.Tx, seq int64, wantReceipt bool, senderID, endpoi
|
||||
return nil
|
||||
}
|
||||
|
||||
// tryFinalizeTx 若无 pending 则收尾。
|
||||
func tryFinalizeTx(tx *sql.Tx, seq int64, nowMs int64, recordDays int) error {
|
||||
// TryFinalizeTx 若无 pending 则收尾。
|
||||
func TryFinalizeTx(tx *sql.Tx, seq int64, nowMs int64, recordDays int) error {
|
||||
var n int
|
||||
if err := tx.QueryRow(`SELECT COUNT(*) FROM deliveries WHERE seq = ? AND state = 'pending'`, seq).Scan(&n); err != nil {
|
||||
return err
|
||||
@@ -261,7 +264,46 @@ func tryFinalizeTx(tx *sql.Tx, seq int64, nowMs int64, recordDays int) error {
|
||||
}
|
||||
return err
|
||||
}
|
||||
return finalizeMessageTx(tx, seq, receipt != 0, senderID, "", "", nowMs, recordDays)
|
||||
return FinalizeMessageTx(tx, seq, receipt != 0, senderID, "", "", nowMs, recordDays)
|
||||
}
|
||||
|
||||
func skipVoidReceipt(reason string) bool {
|
||||
return reason == "sender_disabled" || reason == "sender_deleted"
|
||||
}
|
||||
|
||||
// RejectPendingTx 把一条 pending 投递改为 rejected;消息要求回执且发送方存在时写回执。
|
||||
// 停用/删除发送方(sender_disabled / sender_deleted)不写回执(DEVELOPMENT 7.6)。
|
||||
// 返回该投递是否曾推送,供调用方发 revoked。
|
||||
func RejectPendingTx(tx *sql.Tx, seq int64, endpointID, reason string, nowMs int64) (pushed bool, err error) {
|
||||
var pushedAt sql.NullInt64
|
||||
err = tx.QueryRow(`SELECT pushed_at FROM deliveries WHERE seq = ? AND endpoint_id = ?`, seq, endpointID).Scan(&pushedAt)
|
||||
if err == sql.ErrNoRows {
|
||||
return false, nil
|
||||
}
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
res, err := tx.Exec(`
|
||||
UPDATE deliveries SET state = ?, reason = ?, updated_at = ?
|
||||
WHERE seq = ? AND endpoint_id = ? AND state = ?`,
|
||||
DeliveryRejected, reason, nowMs, seq, endpointID, DeliveryPending)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
aff, _ := res.RowsAffected()
|
||||
if aff == 0 {
|
||||
return false, nil
|
||||
}
|
||||
if !skipVoidReceipt(reason) {
|
||||
var senderID string
|
||||
if err := tx.QueryRow(`SELECT sender_id FROM messages WHERE seq = ?`, seq).Scan(&senderID); err != nil {
|
||||
return false, err
|
||||
}
|
||||
if err := insertReceiptTx(tx, senderID, seq, endpointID, DeliveryRejected, reason, nowMs); err != nil {
|
||||
return false, err
|
||||
}
|
||||
}
|
||||
return pushedAt.Valid, nil
|
||||
}
|
||||
|
||||
func insertReceiptTx(tx *sql.Tx, senderID string, seq int64, endpointID, state, reason string, nowMs int64) error {
|
||||
|
||||
Reference in New Issue
Block a user