fix(notify): 根治低带宽控制面阻塞与传输写入卡死
- 为控制消息增加优先级、公平调度、队列字节预算和自适应批处理 - 支持可取消的写门等待,收紧 shared/dedicated bulk、stream 和 Reply 写入边界 - 修复 bulk reset/close、连接 handoff 和安全 profile 切换时序 - 保留旧取消与超时错误契约,新增阶段化 TransportSendError - 增加 ReplyCtx、ReplyObjCtx、写超时配置及黑洞连接和竞态回归测试
This commit is contained in:
+30
-11
@@ -9,9 +9,20 @@ import (
|
||||
)
|
||||
|
||||
func (c *ClientCommon) send(msg TransferMsg) (WaitMsg, error) {
|
||||
return c.sendWithContext(context.Background(), msg)
|
||||
}
|
||||
|
||||
func (c *ClientCommon) sendWithContext(ctx context.Context, msg TransferMsg) (WaitMsg, error) {
|
||||
return c.sendWithContextTimeout(ctx, msg, 0)
|
||||
}
|
||||
|
||||
func (c *ClientCommon) sendWithContextTimeout(ctx context.Context, msg TransferMsg, writeTimeout time.Duration) (WaitMsg, error) {
|
||||
if err := c.ensureClientSendReady(); err != nil {
|
||||
return WaitMsg{}, err
|
||||
}
|
||||
if ctx == nil {
|
||||
ctx = context.Background()
|
||||
}
|
||||
var wait WaitMsg
|
||||
if msg.Type != MSG_SYNC_REPLY && msg.Type != MSG_KEY_CHANGE && msg.Type != MSG_SYS_REPLY || msg.ID == 0 {
|
||||
msg.ID = atomic.AddUint64(&c.msgID, 1)
|
||||
@@ -20,6 +31,8 @@ func (c *ClientCommon) send(msg TransferMsg) (WaitMsg, error) {
|
||||
if err != nil {
|
||||
return WaitMsg{}, err
|
||||
}
|
||||
env.controlCtx = ctx
|
||||
env.controlTimeout = writeTimeout
|
||||
if requiresSignalReplyWait(msg) {
|
||||
wait = c.getPendingWaitPool().createAndStore(msg)
|
||||
}
|
||||
@@ -42,9 +55,9 @@ func (c *ClientCommon) sendEnvelope(env Envelope) error {
|
||||
return err
|
||||
}
|
||||
if batchedControlEnvelope(env) {
|
||||
return c.writeControlPayloadToTransport(payload)
|
||||
return c.writeControlPayloadToTransportTimeout(env.controlContext(), payload, env.controlPriority, env.controlTimeout)
|
||||
}
|
||||
return c.writePayloadToTransport(payload)
|
||||
return c.writePayloadToTransportContextTimeout(env.controlContext(), payload, env.controlTimeout)
|
||||
}
|
||||
|
||||
func (c *ClientCommon) dispatchEnvelope(env Envelope, now time.Time) {
|
||||
@@ -90,12 +103,18 @@ func (c *ClientCommon) Send(key string, value MsgVal) error {
|
||||
}
|
||||
|
||||
func (c *ClientCommon) sendWait(msg TransferMsg, timeout time.Duration) (Message, error) {
|
||||
data, err := c.send(msg)
|
||||
ctx := context.Background()
|
||||
cancel := func() {}
|
||||
if timeout != 0 {
|
||||
ctx, cancel = context.WithTimeout(ctx, timeout)
|
||||
}
|
||||
defer cancel()
|
||||
data, err := c.sendWithContext(ctx, msg)
|
||||
if err != nil {
|
||||
return Message{}, err
|
||||
return Message{}, publicContextSendError(ctx, err)
|
||||
}
|
||||
stopCh := sessionStopChan(c.clientStopContextSnapshot())
|
||||
if timeout.Seconds() == 0 {
|
||||
if timeout == 0 {
|
||||
msg, ok := <-data.Reply
|
||||
if !ok {
|
||||
return msg, pendingWaitClosedErrorWith(stopCh, clientTransportDetachedError(c))
|
||||
@@ -103,7 +122,7 @@ func (c *ClientCommon) sendWait(msg TransferMsg, timeout time.Duration) (Message
|
||||
return msg, nil
|
||||
}
|
||||
select {
|
||||
case <-time.After(timeout):
|
||||
case <-ctx.Done():
|
||||
c.getPendingWaitPool().removeAndClose(data.TransferMsg.ID)
|
||||
return Message{}, os.ErrDeadlineExceeded
|
||||
case <-stopCh:
|
||||
@@ -117,14 +136,14 @@ func (c *ClientCommon) sendWait(msg TransferMsg, timeout time.Duration) (Message
|
||||
}
|
||||
|
||||
func (c *ClientCommon) sendCtx(msg TransferMsg, ctx context.Context) (Message, error) {
|
||||
data, err := c.send(msg)
|
||||
if err != nil {
|
||||
return Message{}, err
|
||||
}
|
||||
stopCh := sessionStopChan(c.clientStopContextSnapshot())
|
||||
if ctx == nil {
|
||||
ctx = context.Background()
|
||||
}
|
||||
data, err := c.sendWithContext(ctx, msg)
|
||||
if err != nil {
|
||||
return Message{}, publicContextSendError(ctx, err)
|
||||
}
|
||||
stopCh := sessionStopChan(c.clientStopContextSnapshot())
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
c.getPendingWaitPool().removeAndClose(data.TransferMsg.ID)
|
||||
|
||||
Reference in New Issue
Block a user