feat(transport): 完成安全架构拆分并收口 stream/bulk 传输优化
- 新增 managed/external/nested 三种传输保护模式 - 新增 peer attach 显式认证、抗重放、channel binding 和可选前向保密协商 - 明确单连接注入与可重拨连接源的语义边界 - 禁止 ConnectByConn 场景下 dedicated bulk 走 sidecar,auto 模式自动回退 shared - 修正 dedicated attach 在 bootstrap/steady profile 切换下的处理逻辑 - 优化 shared bulk super-batch 与批量 framed write 路径 - 降低 stream/bulk fast path 的复制和分发损耗 - 补齐 benchmark、回归测试、运行时快照和 README 文档
This commit is contained in:
+114
-10
@@ -83,7 +83,7 @@ func (r *bulkDedicatedLaneBatchRequest) reset() {
|
||||
}
|
||||
}
|
||||
|
||||
func (r *bulkDedicatedLaneBatchRequest) prepare(ctx context.Context, dataID uint64, items []bulkDedicatedSendRequest, wait bool) {
|
||||
func (r *bulkDedicatedLaneBatchRequest) prepare(ctx context.Context, dataID uint64, items []bulkDedicatedSendRequest, wait bool, borrowItems bool) {
|
||||
if r == nil {
|
||||
return
|
||||
}
|
||||
@@ -94,6 +94,10 @@ func (r *bulkDedicatedLaneBatchRequest) prepare(ctx context.Context, dataID uint
|
||||
if deadline, ok := ctx.Deadline(); ok {
|
||||
r.Deadline = deadline
|
||||
}
|
||||
if borrowItems {
|
||||
r.Items = items
|
||||
return
|
||||
}
|
||||
if cap(r.Items) < len(items) {
|
||||
r.Items = make([]bulkDedicatedSendRequest, len(items))
|
||||
} else {
|
||||
@@ -119,10 +123,10 @@ func (s *bulkDedicatedLaneSender) submitData(ctx context.Context, dataID uint64,
|
||||
Seq: seq,
|
||||
Payload: append([]byte(nil), payload...),
|
||||
}}
|
||||
return s.submitBatch(ctx, dataID, items, false)
|
||||
return s.submitBatch(ctx, dataID, items, false, false)
|
||||
}
|
||||
|
||||
func (s *bulkDedicatedLaneSender) submitWrite(ctx context.Context, dataID uint64, startSeq uint64, payload []byte, chunkSize int) (int, error) {
|
||||
func (s *bulkDedicatedLaneSender) submitWrite(ctx context.Context, dataID uint64, startSeq uint64, payload []byte, chunkSize int, payloadOwned bool) (int, error) {
|
||||
if s == nil {
|
||||
return 0, errTransportDetached
|
||||
}
|
||||
@@ -132,6 +136,9 @@ func (s *bulkDedicatedLaneSender) submitWrite(ctx context.Context, dataID uint64
|
||||
if chunkSize <= 0 {
|
||||
chunkSize = defaultBulkChunkSize
|
||||
}
|
||||
if submitted, written, err := s.tryDirectSubmitWrite(ctx, dataID, startSeq, payload, chunkSize); submitted {
|
||||
return written, err
|
||||
}
|
||||
written := 0
|
||||
seq := startSeq
|
||||
for written < len(payload) {
|
||||
@@ -170,7 +177,7 @@ func (s *bulkDedicatedLaneSender) submitWrite(ctx context.Context, dataID uint64
|
||||
seq++
|
||||
written = end
|
||||
}
|
||||
if err := s.submitWriteBatch(ctx, dataID, items); err != nil {
|
||||
if err := s.submitWriteBatch(ctx, dataID, items, payloadOwned); err != nil {
|
||||
return start, err
|
||||
}
|
||||
start = written
|
||||
@@ -178,7 +185,7 @@ func (s *bulkDedicatedLaneSender) submitWrite(ctx context.Context, dataID uint64
|
||||
return written, nil
|
||||
}
|
||||
|
||||
func (s *bulkDedicatedLaneSender) submitWriteBatch(ctx context.Context, dataID uint64, items []bulkDedicatedSendRequest) error {
|
||||
func (s *bulkDedicatedLaneSender) submitWriteBatch(ctx context.Context, dataID uint64, items []bulkDedicatedSendRequest, _ bool) error {
|
||||
if s == nil {
|
||||
return errTransportDetached
|
||||
}
|
||||
@@ -188,8 +195,7 @@ func (s *bulkDedicatedLaneSender) submitWriteBatch(ctx context.Context, dataID u
|
||||
if submitted, err := s.tryDirectSubmitBatch(ctx, dataID, items); submitted {
|
||||
return err
|
||||
}
|
||||
queuedItems := copyBulkDedicatedSendRequests(items)
|
||||
return s.submitBatch(ctx, dataID, queuedItems, true)
|
||||
return s.submitBatch(ctx, dataID, items, true, true)
|
||||
}
|
||||
|
||||
func (s *bulkDedicatedLaneSender) submitControl(ctx context.Context, dataID uint64, frameType uint8, flags uint8, seq uint64, payload []byte) error {
|
||||
@@ -204,10 +210,10 @@ func (s *bulkDedicatedLaneSender) submitControl(ctx context.Context, dataID uint
|
||||
if len(payload) > 0 {
|
||||
items[0].Payload = append([]byte(nil), payload...)
|
||||
}
|
||||
return s.submitBatch(ctx, dataID, items, true)
|
||||
return s.submitBatch(ctx, dataID, items, true, false)
|
||||
}
|
||||
|
||||
func (s *bulkDedicatedLaneSender) submitBatch(ctx context.Context, dataID uint64, items []bulkDedicatedSendRequest, wait bool) error {
|
||||
func (s *bulkDedicatedLaneSender) submitBatch(ctx context.Context, dataID uint64, items []bulkDedicatedSendRequest, wait bool, borrowItems bool) error {
|
||||
if s == nil {
|
||||
return errTransportDetached
|
||||
}
|
||||
@@ -218,7 +224,7 @@ func (s *bulkDedicatedLaneSender) submitBatch(ctx context.Context, dataID uint64
|
||||
return err
|
||||
}
|
||||
req := getBulkDedicatedLaneBatchRequest()
|
||||
req.prepare(ctx, dataID, items, wait)
|
||||
req.prepare(ctx, dataID, items, wait, borrowItems)
|
||||
s.queued.Add(1)
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
@@ -237,6 +243,104 @@ func (s *bulkDedicatedLaneSender) submitBatch(ctx context.Context, dataID uint64
|
||||
}
|
||||
}
|
||||
|
||||
func (s *bulkDedicatedLaneSender) tryDirectSubmitWrite(ctx context.Context, dataID uint64, startSeq uint64, payload []byte, chunkSize int) (bool, int, error) {
|
||||
if s == nil {
|
||||
return true, 0, errTransportDetached
|
||||
}
|
||||
if ctx == nil {
|
||||
ctx = context.Background()
|
||||
}
|
||||
if len(payload) == 0 {
|
||||
return true, 0, nil
|
||||
}
|
||||
if chunkSize <= 0 {
|
||||
chunkSize = defaultBulkChunkSize
|
||||
}
|
||||
if err := s.errSnapshot(); err != nil {
|
||||
return true, 0, err
|
||||
}
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return true, 0, normalizeStreamDeadlineError(ctx.Err())
|
||||
case <-s.stopCh:
|
||||
return true, 0, s.stoppedErr()
|
||||
default:
|
||||
}
|
||||
if s.queued.Load() != 0 {
|
||||
return false, 0, nil
|
||||
}
|
||||
if !s.flushMu.TryLock() {
|
||||
return false, 0, nil
|
||||
}
|
||||
defer s.flushMu.Unlock()
|
||||
if s.queued.Load() != 0 {
|
||||
return false, 0, nil
|
||||
}
|
||||
if err := s.errSnapshot(); err != nil {
|
||||
return true, 0, err
|
||||
}
|
||||
written := 0
|
||||
seq := startSeq
|
||||
deadline, _ := ctx.Deadline()
|
||||
for written < len(payload) {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return true, written, normalizeStreamDeadlineError(ctx.Err())
|
||||
case <-s.stopCh:
|
||||
return true, written, s.stoppedErr()
|
||||
default:
|
||||
}
|
||||
var itemBuf [bulkDedicatedBatchMaxItems]bulkDedicatedSendRequest
|
||||
items := itemBuf[:0]
|
||||
batchBytes := bulkDedicatedBatchHeaderLen
|
||||
start := written
|
||||
for written < len(payload) && len(items) < bulkDedicatedBatchMaxItems {
|
||||
end := written + chunkSize
|
||||
if end > len(payload) {
|
||||
end = len(payload)
|
||||
}
|
||||
itemLen := bulkDedicatedSendRequestLenFromPayloadLen(end - written)
|
||||
if len(items) > 0 && batchBytes+itemLen > bulkDedicatedBatchMaxPlainBytes {
|
||||
break
|
||||
}
|
||||
items = append(items, bulkDedicatedSendRequest{
|
||||
Type: bulkFastPayloadTypeData,
|
||||
Seq: seq,
|
||||
Payload: payload[written:end],
|
||||
})
|
||||
batchBytes += itemLen
|
||||
seq++
|
||||
written = end
|
||||
}
|
||||
if len(items) == 0 {
|
||||
end := written + chunkSize
|
||||
if end > len(payload) {
|
||||
end = len(payload)
|
||||
}
|
||||
items = append(items, bulkDedicatedSendRequest{
|
||||
Type: bulkFastPayloadTypeData,
|
||||
Seq: seq,
|
||||
Payload: payload[written:end],
|
||||
})
|
||||
seq++
|
||||
written = end
|
||||
}
|
||||
if err := s.flush([]bulkDedicatedOutboundBatch{{
|
||||
DataID: dataID,
|
||||
Items: items,
|
||||
}}, deadline); err != nil {
|
||||
err = normalizeDedicatedBulkSendError(err)
|
||||
s.setErr(err)
|
||||
s.failPending(err)
|
||||
if s.fail != nil {
|
||||
go s.fail(err)
|
||||
}
|
||||
return true, start, err
|
||||
}
|
||||
}
|
||||
return true, written, nil
|
||||
}
|
||||
|
||||
func (s *bulkDedicatedLaneSender) tryDirectSubmitBatch(ctx context.Context, dataID uint64, items []bulkDedicatedSendRequest) (bool, error) {
|
||||
if s == nil {
|
||||
return true, errTransportDetached
|
||||
|
||||
Reference in New Issue
Block a user