notify/connection_retry_state.go
starainrt 09d972c7b7
feat(notify): 重构通信内核并补齐 stream/bulk/record/transfer 能力
- 引入 LogicalConn/TransportConn 分层,ClientConn 保留兼容适配层
  - 新增 Stream、Bulk、RecordStream 三条数据面能力及对应控制路径
  - 完成 transfer/file 传输内核与状态快照、诊断能力
  - 补齐 reconnect、inbound dispatcher、modern psk 等基础模块
  - 增加大规模回归、并发与基准测试覆盖
  - 更新依赖库
2026-04-15 15:24:36 +08:00

148 lines
3.4 KiB
Go

package notify
import (
"sync"
"time"
)
type ConnectionRetrySnapshot struct {
RetryEventTotal uint64
LastRetryAttempt int
LastRetryDelay time.Duration
LastRetryError string
LastRetryAt time.Time
LastResultError string
LastResultAt time.Time
}
type connectionRetryState struct {
mu sync.Mutex
retryEventTotal uint64
lastRetryAttempt int
lastRetryDelay time.Duration
lastRetryError string
lastRetryAt time.Time
lastResultError string
lastResultAt time.Time
}
func newConnectionRetryState() *connectionRetryState {
return &connectionRetryState{}
}
func (s *connectionRetryState) recordRetryEvent(event ConnectRetryEvent) {
if s == nil {
return
}
s.mu.Lock()
defer s.mu.Unlock()
s.retryEventTotal++
s.lastRetryAttempt = event.Attempt
s.lastRetryDelay = event.NextDelay
if event.Err != nil {
s.lastRetryError = event.Err.Error()
} else {
s.lastRetryError = ""
}
s.lastRetryAt = time.Now()
}
func (s *connectionRetryState) recordResult(err error) {
if s == nil {
return
}
s.mu.Lock()
defer s.mu.Unlock()
if err != nil {
s.lastResultError = err.Error()
} else {
s.lastResultError = ""
}
s.lastResultAt = time.Now()
}
func (s *connectionRetryState) snapshot() ConnectionRetrySnapshot {
if s == nil {
return ConnectionRetrySnapshot{}
}
s.mu.Lock()
defer s.mu.Unlock()
return ConnectionRetrySnapshot{
RetryEventTotal: s.retryEventTotal,
LastRetryAttempt: s.lastRetryAttempt,
LastRetryDelay: s.lastRetryDelay,
LastRetryError: s.lastRetryError,
LastRetryAt: s.lastRetryAt,
LastResultError: s.lastResultError,
LastResultAt: s.lastResultAt,
}
}
type connectionRetryRecorder interface {
recordConnectionRetryEvent(event ConnectRetryEvent)
recordConnectionRetryResult(err error)
}
func wrapConnectRetryOptionsWithRecorder(opts *ConnectRetryOptions, recorder connectionRetryRecorder) *ConnectRetryOptions {
if recorder == nil {
return opts
}
if opts == nil {
return &ConnectRetryOptions{
OnRetry: recorder.recordConnectionRetryEvent,
}
}
next := *opts
originOnRetry := next.OnRetry
next.OnRetry = func(event ConnectRetryEvent) {
recorder.recordConnectionRetryEvent(event)
if originOnRetry != nil {
originOnRetry(event)
}
}
return &next
}
func (c *ClientCommon) getConnectionRetryState() *connectionRetryState {
c.mu.Lock()
defer c.mu.Unlock()
if c.connectionRetryState == nil {
c.connectionRetryState = newConnectionRetryState()
}
return c.connectionRetryState
}
func (c *ClientCommon) recordConnectionRetryEvent(event ConnectRetryEvent) {
c.getConnectionRetryState().recordRetryEvent(event)
}
func (c *ClientCommon) recordConnectionRetryResult(err error) {
c.getConnectionRetryState().recordResult(err)
}
func (c *ClientCommon) connectionRetrySnapshot() ConnectionRetrySnapshot {
return c.getConnectionRetryState().snapshot()
}
func (s *ServerCommon) getConnectionRetryState() *connectionRetryState {
s.mu.Lock()
defer s.mu.Unlock()
if s.connectionRetryState == nil {
s.connectionRetryState = newConnectionRetryState()
}
return s.connectionRetryState
}
func (s *ServerCommon) recordConnectionRetryEvent(event ConnectRetryEvent) {
s.getConnectionRetryState().recordRetryEvent(event)
}
func (s *ServerCommon) recordConnectionRetryResult(err error) {
s.getConnectionRetryState().recordResult(err)
}
func (s *ServerCommon) connectionRetrySnapshot() ConnectionRetrySnapshot {
return s.getConnectionRetryState().snapshot()
}