feat(notify): 重构通信内核并补齐 stream/bulk/record/transfer 能力
- 引入 LogicalConn/TransportConn 分层,ClientConn 保留兼容适配层 - 新增 Stream、Bulk、RecordStream 三条数据面能力及对应控制路径 - 完成 transfer/file 传输内核与状态快照、诊断能力 - 补齐 reconnect、inbound dispatcher、modern psk 等基础模块 - 增加大规模回归、并发与基准测试覆盖 - 更新依赖库
This commit is contained in:
@@ -0,0 +1,174 @@
|
||||
package notify
|
||||
|
||||
import "sync"
|
||||
|
||||
const defaultFileTransferCompletedLimit = 128
|
||||
|
||||
type fileTransferMonitor struct {
|
||||
mu sync.Mutex
|
||||
active map[string]fileTransferSnapshot
|
||||
completed map[string]fileTransferSnapshot
|
||||
runtimeActive map[string]fileTransferSnapshot
|
||||
runtimeCompleted map[string]fileTransferSnapshot
|
||||
completedLimit int
|
||||
}
|
||||
|
||||
func newFileTransferMonitor() *fileTransferMonitor {
|
||||
return newFileTransferMonitorWithConfig(defaultFileTransferConfig())
|
||||
}
|
||||
|
||||
func newFileTransferMonitorWithConfig(cfg fileTransferConfig) *fileTransferMonitor {
|
||||
cfg = normalizeFileTransferConfig(cfg)
|
||||
return newFileTransferMonitorWithCompletedLimit(cfg.MonitorCompletedLimit)
|
||||
}
|
||||
|
||||
func newFileTransferMonitorWithCompletedLimit(limit int) *fileTransferMonitor {
|
||||
if limit <= 0 {
|
||||
limit = defaultFileTransferCompletedLimit
|
||||
}
|
||||
return &fileTransferMonitor{
|
||||
active: make(map[string]fileTransferSnapshot),
|
||||
completed: make(map[string]fileTransferSnapshot),
|
||||
runtimeActive: make(map[string]fileTransferSnapshot),
|
||||
runtimeCompleted: make(map[string]fileTransferSnapshot),
|
||||
completedLimit: limit,
|
||||
}
|
||||
}
|
||||
|
||||
func (m *fileTransferMonitor) applyConfig(cfg fileTransferConfig) {
|
||||
if m == nil {
|
||||
return
|
||||
}
|
||||
cfg = normalizeFileTransferConfig(cfg)
|
||||
m.mu.Lock()
|
||||
m.completedLimit = cfg.MonitorCompletedLimit
|
||||
m.trimCompletedLocked()
|
||||
m.mu.Unlock()
|
||||
}
|
||||
|
||||
func (m *fileTransferMonitor) observe(direction fileTransferDirection, event FileEvent) {
|
||||
if m == nil {
|
||||
return
|
||||
}
|
||||
if !isFileTransferObservable(event.Kind) {
|
||||
return
|
||||
}
|
||||
snapshot := fileTransferSnapshotFromEvent(direction, event)
|
||||
key := fileTransferMonitorKey(direction, snapshot.Scope, snapshot.FileID)
|
||||
runtimeKey := fileTransferRuntimeMonitorKey(direction, snapshot.RuntimeScope, snapshot.FileID)
|
||||
if key == "" || runtimeKey == "" {
|
||||
return
|
||||
}
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
if isFileTransferTerminal(snapshot.Kind) {
|
||||
delete(m.active, key)
|
||||
m.completed[key] = snapshot
|
||||
delete(m.runtimeActive, runtimeKey)
|
||||
m.runtimeCompleted[runtimeKey] = snapshot
|
||||
m.trimCompletedLocked()
|
||||
return
|
||||
}
|
||||
delete(m.completed, key)
|
||||
m.active[key] = snapshot
|
||||
delete(m.runtimeCompleted, runtimeKey)
|
||||
m.runtimeActive[runtimeKey] = snapshot
|
||||
}
|
||||
|
||||
func (m *fileTransferMonitor) activeSnapshots() []fileTransferSnapshot {
|
||||
if m == nil {
|
||||
return nil
|
||||
}
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
return sortedFileTransferSnapshots(m.active)
|
||||
}
|
||||
|
||||
func (m *fileTransferMonitor) activeSnapshotsByDirection(direction fileTransferDirection) []fileTransferSnapshot {
|
||||
if m == nil {
|
||||
return nil
|
||||
}
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
return filteredFileTransferSnapshots(m.active, direction)
|
||||
}
|
||||
|
||||
func (m *fileTransferMonitor) completedSnapshots() []fileTransferSnapshot {
|
||||
if m == nil {
|
||||
return nil
|
||||
}
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
return sortedFileTransferSnapshots(m.completed)
|
||||
}
|
||||
|
||||
func (m *fileTransferMonitor) completedSnapshotsByDirection(direction fileTransferDirection) []fileTransferSnapshot {
|
||||
if m == nil {
|
||||
return nil
|
||||
}
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
return filteredFileTransferSnapshots(m.completed, direction)
|
||||
}
|
||||
|
||||
func (m *fileTransferMonitor) latestSnapshot(direction fileTransferDirection, scope string, fileID string) (fileTransferSnapshot, bool) {
|
||||
if m == nil {
|
||||
return fileTransferSnapshot{}, false
|
||||
}
|
||||
key := fileTransferMonitorKey(direction, scope, fileID)
|
||||
if key == "" {
|
||||
return fileTransferSnapshot{}, false
|
||||
}
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
if snapshot, ok := m.active[key]; ok {
|
||||
return snapshot, true
|
||||
}
|
||||
snapshot, ok := m.completed[key]
|
||||
return snapshot, ok
|
||||
}
|
||||
|
||||
func (m *fileTransferMonitor) snapshotsByFileID(fileID string) []fileTransferSnapshot {
|
||||
if m == nil || fileID == "" {
|
||||
return nil
|
||||
}
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
latest := latestFileTransferSnapshotsLocked(m.active, m.completed)
|
||||
return filterFileTransferSnapshotsByFileID(latest, fileID)
|
||||
}
|
||||
|
||||
func (m *fileTransferMonitor) snapshotsByDirectionAndFileID(direction fileTransferDirection, fileID string) []fileTransferSnapshot {
|
||||
if m == nil || fileID == "" {
|
||||
return nil
|
||||
}
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
latest := latestFileTransferSnapshotsLocked(m.active, m.completed)
|
||||
return filterFileTransferSnapshotsByDirectionAndFileID(latest, direction, fileID)
|
||||
}
|
||||
|
||||
func (m *fileTransferMonitor) trimCompletedLocked() {
|
||||
trimFileTransferSnapshotsLocked(m.completed, m.completedLimit)
|
||||
trimFileTransferSnapshotsLocked(m.runtimeCompleted, m.completedLimit)
|
||||
}
|
||||
|
||||
func trimFileTransferSnapshotsLocked(snapshots map[string]fileTransferSnapshot, limit int) {
|
||||
if limit <= 0 || len(snapshots) <= limit {
|
||||
return
|
||||
}
|
||||
for len(snapshots) > limit {
|
||||
oldestKey := ""
|
||||
oldestSnapshot := fileTransferSnapshot{}
|
||||
for key, snapshot := range snapshots {
|
||||
if oldestKey == "" || fileTransferSnapshotOlder(snapshot, oldestSnapshot, key, oldestKey) {
|
||||
oldestKey = key
|
||||
oldestSnapshot = snapshot
|
||||
}
|
||||
}
|
||||
if oldestKey == "" {
|
||||
return
|
||||
}
|
||||
delete(snapshots, oldestKey)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user