fix: 仅向已握手连接推送并拆分调度循环
This commit is contained in:
@@ -3,6 +3,7 @@ package message
|
||||
import (
|
||||
"database/sql"
|
||||
"encoding/base64"
|
||||
"time"
|
||||
|
||||
"git.asio.asia/nixevol/NixMsg/internal/protocol"
|
||||
)
|
||||
@@ -36,10 +37,16 @@ const (
|
||||
|
||||
const (
|
||||
packetOverheadBudget = 128
|
||||
largeFrameBytes = 64 * 1024
|
||||
maxLargeInflight = 64
|
||||
defaultDeliveryWindow = 32
|
||||
defaultReceiptWindow = 64
|
||||
dispatchConcurrency = 8
|
||||
dispatchBudget = 250 * time.Millisecond
|
||||
expireBatch = 500
|
||||
expireBudget = 200 * time.Millisecond
|
||||
purgeRowBatch = 2000
|
||||
purgeMsgBatch = 80
|
||||
clearPushedTimeout = 5 * time.Second
|
||||
pushOpTimeout = 30 * time.Second
|
||||
)
|
||||
|
||||
// dispatchFullTx 按 DEVELOPMENT 7.4 完整分发一条已到点的 scheduled 消息。
|
||||
@@ -157,8 +164,13 @@ WHERE endpoint_id = ? AND state = 'pending'`, r.id).Scan(&n); err != nil {
|
||||
case !online && keepBool:
|
||||
expireAt = sql.NullInt64{Int64: nowMs + ttlSeconds*1000, Valid: true}
|
||||
default:
|
||||
var offlineSince sql.NullInt64
|
||||
_ = tx.QueryRow(`SELECT offline_since FROM endpoints WHERE id = ?`, r.id).Scan(&offlineSince)
|
||||
var onlineSince, offlineSince sql.NullInt64
|
||||
_ = tx.QueryRow(`SELECT online_since, offline_since FROM endpoints WHERE id = ?`, r.id).Scan(&onlineSince, &offlineSince)
|
||||
dbShowsOnline := onlineSince.Valid && (!offlineSince.Valid || onlineSince.Int64 > offlineSince.Int64)
|
||||
if dbShowsOnline {
|
||||
expireAt = sql.NullInt64{Int64: nowMs + graceMs, Valid: true}
|
||||
break
|
||||
}
|
||||
if !offlineSince.Valid {
|
||||
dState = DeliveryDropped
|
||||
reason = ReasonOffline
|
||||
@@ -182,7 +194,7 @@ VALUES(?,?,?,?,?,?,?,NULL,NULL,0,?)`,
|
||||
if dState == DeliveryPending {
|
||||
pendingAny = true
|
||||
} else if wantReceipt {
|
||||
if err := insertReceiptTx(tx, senderID, seq, r.id, dState, reason, nowMs); err != nil {
|
||||
if _, err := insertReceiptTx(tx, senderID, seq, r.id, dState, reason, nowMs); err != nil {
|
||||
return "", true, err
|
||||
}
|
||||
}
|
||||
@@ -223,7 +235,7 @@ func FinalizeMessageTx(tx *sql.Tx, seq int64, wantReceipt bool, senderID, endpoi
|
||||
return err
|
||||
}
|
||||
if msgReason != "" && wantReceipt && receipt != 0 {
|
||||
if err := insertReceiptTx(tx, senderID, seq, endpointID, DeliveryRejected, msgReason, nowMs); err != nil {
|
||||
if _, err := insertReceiptTx(tx, senderID, seq, endpointID, DeliveryRejected, msgReason, nowMs); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -298,35 +310,37 @@ WHERE seq = ? AND endpoint_id = ? AND state = ?`,
|
||||
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 {
|
||||
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 {
|
||||
func insertReceiptTx(tx *sql.Tx, senderID string, seq int64, endpointID, state, reason string, nowMs int64) (bool, error) {
|
||||
var msgID string
|
||||
var want int
|
||||
if err := tx.QueryRow(`SELECT id, receipt FROM messages WHERE seq = ?`, seq).Scan(&msgID, &want); err != nil {
|
||||
return err
|
||||
return false, err
|
||||
}
|
||||
if want == 0 {
|
||||
return nil
|
||||
return false, nil
|
||||
}
|
||||
// 发送方仍存在
|
||||
var one int
|
||||
err := tx.QueryRow(`SELECT 1 FROM endpoints WHERE id = ?`, senderID).Scan(&one)
|
||||
if err == sql.ErrNoRows {
|
||||
return nil
|
||||
return false, nil
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
return false, err
|
||||
}
|
||||
_, err = tx.Exec(`
|
||||
INSERT INTO receipts(sender_id, msg_id, endpoint_id, state, reason, created_at, acked)
|
||||
VALUES(?,?,?,?,?,?,0)`, senderID, msgID, endpointID, state, reason, nowMs)
|
||||
return err
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func encodeStoredBody(enc, contentType string, raw []byte) protocol.Body {
|
||||
|
||||
Reference in New Issue
Block a user