feat: 完善 RecordStream 的协议协商、运行观测与文档说明
- 将 RecordStream 出站路径收敛为单 writer loop - 支持在 batch header 中 piggyback AckSeq,保留独立 ack 作为兼容回退 - 增加 record stream 打开阶段能力协商,支持 mixed-version peer 自动降级 - 补充 RecordSnapshot 与 diagnostics summary 的 record-plane 观测项 - 增加 batch/ack/error frame、piggyback ack、barrier 等待拆分与 apply backlog 指标 - 收紧 TransportConn detach 后的 runtime snapshot 语义 - 补充 README 中的 RecordStream 语义、兼容行为与诊断快照说明 - 补充相关单测与 race 回归验证
This commit is contained in:
@@ -34,6 +34,27 @@ type DiagnosticsTransferTelemetrySummary struct {
|
||||
CommitWaitRatio float64
|
||||
}
|
||||
|
||||
type DiagnosticsRecordTelemetrySummary struct {
|
||||
BatchFramesSent int64
|
||||
AckFramesSent int64
|
||||
ErrorFramesSent int64
|
||||
BatchFramesReceived int64
|
||||
AckFramesReceived int64
|
||||
ErrorFramesReceived int64
|
||||
FrameSendCount int64
|
||||
FrameReceiveCount int64
|
||||
PiggybackAckSent int64
|
||||
PiggybackAckReceived int64
|
||||
BarrierCount int64
|
||||
BarrierFlushWaitDuration time.Duration
|
||||
BarrierApplyWaitDuration time.Duration
|
||||
OutstandingRecords int
|
||||
OutstandingBytes int
|
||||
PendingApplyRecords int
|
||||
PendingAckRecords int
|
||||
PeakPendingApplyRecords int
|
||||
}
|
||||
|
||||
type DiagnosticsSummary struct {
|
||||
LogicalCount int
|
||||
CurrentTransportCount int
|
||||
@@ -49,6 +70,11 @@ type DiagnosticsSummary struct {
|
||||
StaleBulkCount int
|
||||
ResetBulkCount int
|
||||
|
||||
RecordCount int
|
||||
ActiveRecordCount int
|
||||
StaleRecordCount int
|
||||
ResetRecordCount int
|
||||
|
||||
TransferCount int
|
||||
ActiveTransferCount int
|
||||
PausedTransferCount int
|
||||
@@ -58,6 +84,8 @@ type DiagnosticsSummary struct {
|
||||
|
||||
StreamResetCauses DiagnosticsResetCauseSummary
|
||||
BulkResetCauses DiagnosticsResetCauseSummary
|
||||
RecordResetCauses DiagnosticsResetCauseSummary
|
||||
RecordTelemetry DiagnosticsRecordTelemetrySummary
|
||||
TransferTelemetry DiagnosticsTransferTelemetrySummary
|
||||
}
|
||||
|
||||
@@ -65,6 +93,7 @@ type ClientDiagnosticsSnapshot struct {
|
||||
Runtime ClientRuntimeSnapshot
|
||||
Streams []StreamSnapshot
|
||||
Bulks []BulkSnapshot
|
||||
Records []RecordSnapshot
|
||||
Transfers []TransferSnapshot
|
||||
Summary DiagnosticsSummary
|
||||
}
|
||||
@@ -75,6 +104,7 @@ type ServerDiagnosticsSnapshot struct {
|
||||
CurrentTransports []TransportConnRuntimeSnapshot
|
||||
Streams []StreamSnapshot
|
||||
Bulks []BulkSnapshot
|
||||
Records []RecordSnapshot
|
||||
Transfers []TransferSnapshot
|
||||
Summary DiagnosticsSummary
|
||||
}
|
||||
@@ -100,6 +130,10 @@ func GetClientDiagnosticsSnapshot(c Client) (ClientDiagnosticsSnapshot, error) {
|
||||
if err != nil {
|
||||
return ClientDiagnosticsSnapshot{}, err
|
||||
}
|
||||
records, err := GetClientRecordSnapshots(c)
|
||||
if err != nil {
|
||||
return ClientDiagnosticsSnapshot{}, err
|
||||
}
|
||||
transfers, err := GetClientTransferSnapshots(c)
|
||||
if err != nil {
|
||||
return ClientDiagnosticsSnapshot{}, err
|
||||
@@ -108,6 +142,7 @@ func GetClientDiagnosticsSnapshot(c Client) (ClientDiagnosticsSnapshot, error) {
|
||||
Runtime: runtime,
|
||||
Streams: streams,
|
||||
Bulks: bulks,
|
||||
Records: records,
|
||||
Transfers: transfers,
|
||||
}
|
||||
snapshot.Summary = summarizeClientDiagnosticsSnapshot(snapshot)
|
||||
@@ -138,6 +173,10 @@ func GetServerDiagnosticsSnapshot(s Server) (ServerDiagnosticsSnapshot, error) {
|
||||
if err != nil {
|
||||
return ServerDiagnosticsSnapshot{}, err
|
||||
}
|
||||
records, err := GetServerRecordSnapshots(s)
|
||||
if err != nil {
|
||||
return ServerDiagnosticsSnapshot{}, err
|
||||
}
|
||||
transfers, err := GetServerTransferSnapshots(s)
|
||||
if err != nil {
|
||||
return ServerDiagnosticsSnapshot{}, err
|
||||
@@ -148,6 +187,7 @@ func GetServerDiagnosticsSnapshot(s Server) (ServerDiagnosticsSnapshot, error) {
|
||||
CurrentTransports: transports,
|
||||
Streams: streams,
|
||||
Bulks: bulks,
|
||||
Records: records,
|
||||
Transfers: transfers,
|
||||
}
|
||||
snapshot.Summary = summarizeServerDiagnosticsSnapshot(snapshot)
|
||||
@@ -203,6 +243,7 @@ func summarizeClientDiagnosticsSnapshot(snapshot ClientDiagnosticsSnapshot) Diag
|
||||
}
|
||||
summarizeStreamSnapshots(&summary, snapshot.Streams)
|
||||
summarizeBulkSnapshots(&summary, snapshot.Bulks)
|
||||
summarizeRecordSnapshots(&summary, snapshot.Records)
|
||||
summarizeTransferSnapshots(&summary, snapshot.Transfers)
|
||||
return summary
|
||||
}
|
||||
@@ -214,6 +255,7 @@ func summarizeServerDiagnosticsSnapshot(snapshot ServerDiagnosticsSnapshot) Diag
|
||||
}
|
||||
summarizeStreamSnapshots(&summary, snapshot.Streams)
|
||||
summarizeBulkSnapshots(&summary, snapshot.Bulks)
|
||||
summarizeRecordSnapshots(&summary, snapshot.Records)
|
||||
summarizeTransferSnapshots(&summary, snapshot.Transfers)
|
||||
return summary
|
||||
}
|
||||
@@ -266,6 +308,27 @@ func summarizeBulkSnapshots(summary *DiagnosticsSummary, snapshots []BulkSnapsho
|
||||
}
|
||||
}
|
||||
|
||||
func summarizeRecordSnapshots(summary *DiagnosticsSummary, snapshots []RecordSnapshot) {
|
||||
if summary == nil {
|
||||
return
|
||||
}
|
||||
summary.RecordCount = len(snapshots)
|
||||
for _, snapshot := range snapshots {
|
||||
switch {
|
||||
case snapshot.ResetError != "":
|
||||
summary.ResetRecordCount++
|
||||
accumulateDiagnosticsResetCause(&summary.RecordResetCauses, snapshot.ResetError, "")
|
||||
case recordSnapshotFinished(snapshot):
|
||||
case recordSnapshotBoundActive(snapshot):
|
||||
summary.ActiveRecordCount++
|
||||
default:
|
||||
summary.StaleRecordCount++
|
||||
}
|
||||
accumulateDiagnosticsRecordTelemetry(&summary.RecordTelemetry, snapshot)
|
||||
}
|
||||
finalizeDiagnosticsRecordTelemetry(&summary.RecordTelemetry)
|
||||
}
|
||||
|
||||
func summarizeTransferSnapshots(summary *DiagnosticsSummary, snapshots []TransferSnapshot) {
|
||||
if summary == nil {
|
||||
return
|
||||
@@ -297,6 +360,10 @@ func bulkSnapshotFinished(snapshot BulkSnapshot) bool {
|
||||
return snapshot.ResetError == "" && snapshot.LocalClosed && snapshot.RemoteClosed
|
||||
}
|
||||
|
||||
func recordSnapshotFinished(snapshot RecordSnapshot) bool {
|
||||
return snapshot.ResetError == "" && snapshot.LocalClosed && snapshot.RemoteClosed
|
||||
}
|
||||
|
||||
func streamSnapshotBoundActive(snapshot StreamSnapshot) bool {
|
||||
return snapshot.BindingCurrent && snapshot.TransportAttached && snapshot.TransportCurrent
|
||||
}
|
||||
@@ -305,6 +372,10 @@ func bulkSnapshotBoundActive(snapshot BulkSnapshot) bool {
|
||||
return snapshot.BindingCurrent && snapshot.TransportAttached && snapshot.TransportCurrent
|
||||
}
|
||||
|
||||
func recordSnapshotBoundActive(snapshot RecordSnapshot) bool {
|
||||
return snapshot.BindingCurrent && snapshot.TransportAttached && snapshot.TransportCurrent
|
||||
}
|
||||
|
||||
func accumulateDiagnosticsResetCause(summary *DiagnosticsResetCauseSummary, resetError string, backpressureError string) {
|
||||
if summary == nil || resetError == "" {
|
||||
return
|
||||
@@ -362,6 +433,38 @@ func finalizeDiagnosticsTransferTelemetry(summary *DiagnosticsTransferTelemetryS
|
||||
summary.CommitWaitRatio = durationRatio(summary.CommitWaitDuration, summary.ObservedDuration)
|
||||
}
|
||||
|
||||
func accumulateDiagnosticsRecordTelemetry(summary *DiagnosticsRecordTelemetrySummary, snapshot RecordSnapshot) {
|
||||
if summary == nil {
|
||||
return
|
||||
}
|
||||
summary.BatchFramesSent += snapshot.BatchFramesSent
|
||||
summary.AckFramesSent += snapshot.AckFramesSent
|
||||
summary.ErrorFramesSent += snapshot.ErrorFramesSent
|
||||
summary.BatchFramesReceived += snapshot.BatchFramesReceived
|
||||
summary.AckFramesReceived += snapshot.AckFramesReceived
|
||||
summary.ErrorFramesReceived += snapshot.ErrorFramesReceived
|
||||
summary.PiggybackAckSent += snapshot.PiggybackAckSent
|
||||
summary.PiggybackAckReceived += snapshot.PiggybackAckReceived
|
||||
summary.BarrierCount += snapshot.BarrierCount
|
||||
summary.BarrierFlushWaitDuration += snapshot.BarrierFlushWaitDuration
|
||||
summary.BarrierApplyWaitDuration += snapshot.BarrierApplyWaitDuration
|
||||
summary.OutstandingRecords += snapshot.OutstandingRecords
|
||||
summary.OutstandingBytes += snapshot.OutstandingBytes
|
||||
summary.PendingApplyRecords += snapshot.PendingApplyRecords
|
||||
summary.PendingAckRecords += snapshot.PendingAckRecords
|
||||
if snapshot.PeakPendingApplyRecords > summary.PeakPendingApplyRecords {
|
||||
summary.PeakPendingApplyRecords = snapshot.PeakPendingApplyRecords
|
||||
}
|
||||
}
|
||||
|
||||
func finalizeDiagnosticsRecordTelemetry(summary *DiagnosticsRecordTelemetrySummary) {
|
||||
if summary == nil {
|
||||
return
|
||||
}
|
||||
summary.FrameSendCount = summary.BatchFramesSent + summary.AckFramesSent + summary.ErrorFramesSent
|
||||
summary.FrameReceiveCount = summary.BatchFramesReceived + summary.AckFramesReceived + summary.ErrorFramesReceived
|
||||
}
|
||||
|
||||
func sortClientConnRuntimeSnapshots(src []ClientConnRuntimeSnapshot) {
|
||||
sort.Slice(src, func(i, j int) bool {
|
||||
if src[i].ClientID != src[j].ClientID {
|
||||
|
||||
Reference in New Issue
Block a user