fix(notify): 根治低带宽控制面阻塞与传输写入卡死

- 为控制消息增加优先级、公平调度、队列字节预算和自适应批处理
- 支持可取消的写门等待,收紧 shared/dedicated bulk、stream 和 Reply 写入边界
- 修复 bulk reset/close、连接 handoff 和安全 profile 切换时序
- 保留旧取消与超时错误契约,新增阶段化 TransportSendError
- 增加 ReplyCtx、ReplyObjCtx、写超时配置及黑洞连接和竞态回归测试
This commit is contained in:
2026-08-14 10:16:37 +08:00
parent 98ef9e7fcc
commit 0826e17063
45 changed files with 4231 additions and 293 deletions
+33 -5
View File
@@ -2,13 +2,16 @@ package notify
import (
"b612.me/notify/internal/timeutil"
"context"
crand "crypto/rand"
"encoding/binary"
"errors"
"fmt"
"os"
"path/filepath"
"strings"
"sync/atomic"
"time"
)
type EnvelopeKind uint8
@@ -30,6 +33,11 @@ type Envelope struct {
Body []byte
Stream StreamPacket
File FilePacket
controlCtx context.Context
controlPriority controlPriority
controlTimeout time.Duration
transportProfile *transportProtectionProfile
}
type StreamPacket struct {
@@ -56,12 +64,31 @@ func wrapTransferMsgEnvelope(msg TransferMsg, enFn func(interface{}) ([]byte, er
return Envelope{}, err
}
return Envelope{
Kind: EnvelopeSignal,
ID: msg.ID,
Body: body,
Kind: EnvelopeSignal,
ID: msg.ID,
Body: body,
controlPriority: controlPriorityForTransferMessage(msg),
}, nil
}
func controlPriorityForTransferMessage(msg TransferMsg) controlPriority {
switch msg.Type {
case MSG_SYS, MSG_SYS_WAIT, MSG_SYS_REPLY, MSG_KEY_CHANGE, MSG_SYNC_REPLY:
return controlPriorityCritical
}
if msg.Key == "heartbeat" || msg.Key == "bye" || strings.HasPrefix(msg.Key, "notify.") {
return controlPriorityCritical
}
return controlPriorityNormal
}
func (env Envelope) controlContext() context.Context {
if env.controlCtx == nil {
return context.Background()
}
return env.controlCtx
}
func unwrapTransferMsgEnvelope(env Envelope, deFn func([]byte) (interface{}, error)) (TransferMsg, error) {
if env.Kind != EnvelopeSignal {
return TransferMsg{}, errors.New("envelope kind is not signal")
@@ -79,8 +106,9 @@ func unwrapTransferMsgEnvelope(env Envelope, deFn func([]byte) (interface{}, err
func newSignalAckEnvelope(signalID uint64) Envelope {
return Envelope{
Kind: EnvelopeSignalAck,
ID: signalID,
Kind: EnvelopeSignalAck,
ID: signalID,
controlPriority: controlPriorityCritical,
}
}