fix: close stream adaptive gaps and switch notify to stario v0.1.1

- make stream fast path honor adaptive soft payload limits end-to-end
  - split oversized fast-stream payloads into sequential frames before batching
  - use adaptive soft cap when encoding stream batch payloads
  - move timeout-like error detection into production code for adaptive tx
  - tune notify FrameReader read size explicitly to avoid throughput regression
  - drop local stario replace and depend on released b612.me/stario v0.1.1
This commit is contained in:
2026-04-18 16:05:57 +08:00
parent 4f760f2807
commit f038a89771
76 changed files with 12656 additions and 906 deletions
+84 -2
View File
@@ -15,9 +15,14 @@ type transportBinding struct {
queue *stario.StarQueue
writeMu sync.Mutex
adaptiveTx adaptiveTxState
controlMu sync.Mutex
controlSender *controlBatchSender
streamMu sync.Mutex
streamSender *streamBatchSender
bulkMu sync.Mutex
bulkSender *bulkBatchSender
}
@@ -71,7 +76,7 @@ func (b *transportBinding) withConnWriteLockDeadline(deadline time.Time, fn func
return fn(conn)
}
func (b *transportBinding) bulkBatchSenderSnapshot() *bulkBatchSender {
func (b *transportBinding) bulkBatchSenderSnapshotWithCodec(codec bulkBatchCodec, writeTimeout func() time.Duration) *bulkBatchSender {
if b == nil {
return nil
}
@@ -80,10 +85,39 @@ func (b *transportBinding) bulkBatchSenderSnapshot() *bulkBatchSender {
if b.bulkSender != nil {
return b.bulkSender
}
b.bulkSender = newBulkBatchSender(b)
b.bulkSender = newBulkBatchSender(b, codec, writeTimeout)
return b.bulkSender
}
func (b *transportBinding) clientBulkBatchSenderSnapshot(c *ClientCommon) *bulkBatchSender {
if b == nil || c == nil {
return nil
}
return b.bulkBatchSenderSnapshotWithCodec(bulkBatchCodec{
encodeSingle: c.encodeBulkFastPayloadPooled,
encodeBatch: c.encodeBulkFastBatchPayloadPooled,
}, c.maxWriteTimeoutSnapshot)
}
func (b *transportBinding) serverBulkBatchSenderSnapshot(logical *LogicalConn) *bulkBatchSender {
if b == nil || logical == nil {
return nil
}
server := logical.Server()
common, ok := server.(*ServerCommon)
if !ok || common == nil {
return nil
}
return b.bulkBatchSenderSnapshotWithCodec(bulkBatchCodec{
encodeSingle: func(frame bulkFastFrame) ([]byte, func(), error) {
return common.encodeBulkFastPayloadLogicalPooled(logical, frame)
},
encodeBatch: func(frames []bulkFastFrame) ([]byte, func(), error) {
return common.encodeBulkFastBatchPayloadLogicalPooled(logical, frames)
},
}, logical.maxWriteTimeoutSnapshot)
}
func (b *transportBinding) controlBatchSenderSnapshot() *controlBatchSender {
if b == nil {
return nil
@@ -97,6 +131,48 @@ func (b *transportBinding) controlBatchSenderSnapshot() *controlBatchSender {
return b.controlSender
}
func (b *transportBinding) streamBatchSenderSnapshotWithCodec(codec streamBatchCodec, writeTimeout func() time.Duration) *streamBatchSender {
if b == nil {
return nil
}
b.streamMu.Lock()
defer b.streamMu.Unlock()
if b.streamSender != nil {
return b.streamSender
}
b.streamSender = newStreamBatchSender(b, codec, writeTimeout)
return b.streamSender
}
func (b *transportBinding) clientStreamBatchSenderSnapshot(c *ClientCommon) *streamBatchSender {
if b == nil || c == nil {
return nil
}
return b.streamBatchSenderSnapshotWithCodec(streamBatchCodec{
encodeSingle: c.encodeFastStreamPayload,
encodeBatch: c.encodeFastStreamBatchPayload,
}, c.maxWriteTimeoutSnapshot)
}
func (b *transportBinding) serverStreamBatchSenderSnapshot(logical *LogicalConn) *streamBatchSender {
if b == nil || logical == nil {
return nil
}
server := logical.Server()
common, ok := server.(*ServerCommon)
if !ok || common == nil {
return nil
}
return b.streamBatchSenderSnapshotWithCodec(streamBatchCodec{
encodeSingle: func(frame streamFastDataFrame) ([]byte, error) {
return common.encodeFastStreamPayloadLogical(logical, frame)
},
encodeBatch: func(frames []streamFastDataFrame) ([]byte, error) {
return common.encodeFastStreamBatchPayloadLogical(logical, frames)
},
}, logical.maxWriteTimeoutSnapshot)
}
func (b *transportBinding) stopBackgroundWorkers() {
if b == nil {
return
@@ -104,12 +180,18 @@ func (b *transportBinding) stopBackgroundWorkers() {
b.controlMu.Lock()
controlSender := b.controlSender
b.controlMu.Unlock()
b.streamMu.Lock()
streamSender := b.streamSender
b.streamMu.Unlock()
b.bulkMu.Lock()
bulkSender := b.bulkSender
b.bulkMu.Unlock()
if controlSender != nil {
controlSender.stop()
}
if streamSender != nil {
streamSender.stop()
}
if bulkSender != nil {
bulkSender.stop()
}