- 引入 LogicalConn/TransportConn 分层,ClientConn 保留兼容适配层 - 新增 Stream、Bulk、RecordStream 三条数据面能力及对应控制路径 - 完成 transfer/file 传输内核与状态快照、诊断能力 - 补齐 reconnect、inbound dispatcher、modern psk 等基础模块 - 增加大规模回归、并发与基准测试覆盖 - 更新依赖库
233 lines
5.0 KiB
Go
233 lines
5.0 KiB
Go
package notify
|
|
|
|
import (
|
|
"context"
|
|
"net"
|
|
)
|
|
|
|
type clientConnSessionRuntime struct {
|
|
transport *transportBinding
|
|
transportAttached bool
|
|
transportGeneration uint64
|
|
tuConn net.Conn
|
|
stopCtx context.Context
|
|
stopFn context.CancelFunc
|
|
transportStopCtx context.Context
|
|
transportStopFn context.CancelFunc
|
|
transportDone chan struct{}
|
|
}
|
|
|
|
func (c *ClientConn) setClientConnSessionRuntime(rt *clientConnSessionRuntime) {
|
|
if c == nil || rt == nil {
|
|
return
|
|
}
|
|
logical := c.LogicalConn()
|
|
if logical == nil {
|
|
if rt.transport == nil && rt.tuConn != nil {
|
|
rt.transport = newTransportBinding(rt.tuConn, nil)
|
|
}
|
|
normalizeClientConnSessionRuntimeTransportState(rt)
|
|
ensureClientConnSessionRuntimeTransportLifecycle(rt)
|
|
ensureClientConnSessionRuntimeTransportDone(rt)
|
|
c.sessionRuntime.Store(rt)
|
|
return
|
|
}
|
|
logical.setSessionRuntime(rt)
|
|
}
|
|
|
|
func (c *ClientConn) clientConnSessionRuntimeSnapshot() *clientConnSessionRuntime {
|
|
if c == nil {
|
|
return nil
|
|
}
|
|
state := c.ensureLogicalConnRuntimeState()
|
|
if state == nil {
|
|
return c.sessionRuntime.Load()
|
|
}
|
|
rt := state.sessionRuntimeSnapshot()
|
|
if rt != c.sessionRuntime.Load() {
|
|
c.sessionRuntime.Store(rt)
|
|
}
|
|
return rt
|
|
}
|
|
|
|
func (c *ClientConn) clearClientConnSessionRuntimeTransport() {
|
|
if c == nil {
|
|
return
|
|
}
|
|
logical := c.LogicalConn()
|
|
if logical == nil {
|
|
rt := c.clientConnSessionRuntimeSnapshot()
|
|
if rt == nil {
|
|
return
|
|
}
|
|
if rt.transportStopFn != nil {
|
|
rt.transportStopFn()
|
|
}
|
|
next := *rt
|
|
next.transport = nil
|
|
next.transportAttached = false
|
|
next.transportGeneration = 0
|
|
next.tuConn = nil
|
|
next.transportStopCtx = nil
|
|
next.transportStopFn = nil
|
|
next.transportDone = nil
|
|
c.setClientConnSessionRuntime(&next)
|
|
return
|
|
}
|
|
logical.clearSessionRuntimeTransport()
|
|
}
|
|
|
|
func (c *ClientConn) clientConnTransportSnapshot() net.Conn {
|
|
logical := c.LogicalConn()
|
|
if logical == nil {
|
|
rt := c.clientConnSessionRuntimeSnapshot()
|
|
if rt == nil {
|
|
return nil
|
|
}
|
|
if rt.transport != nil {
|
|
return rt.transport.connSnapshot()
|
|
}
|
|
return rt.tuConn
|
|
}
|
|
return logical.transportSnapshot()
|
|
}
|
|
|
|
func (c *ClientConn) clientConnStopContextSnapshot() context.Context {
|
|
logical := c.LogicalConn()
|
|
if logical == nil {
|
|
rt := c.clientConnSessionRuntimeSnapshot()
|
|
if rt == nil {
|
|
return nil
|
|
}
|
|
return rt.stopCtx
|
|
}
|
|
return logical.stopContextSnapshot()
|
|
}
|
|
|
|
func (c *ClientConn) clientConnStopFuncSnapshot() context.CancelFunc {
|
|
logical := c.LogicalConn()
|
|
if logical == nil {
|
|
rt := c.clientConnSessionRuntimeSnapshot()
|
|
if rt == nil {
|
|
return nil
|
|
}
|
|
return rt.stopFn
|
|
}
|
|
return logical.stopFuncSnapshot()
|
|
}
|
|
|
|
func (c *ClientConn) closeClientConnTransport() {
|
|
logical := c.LogicalConn()
|
|
if logical == nil {
|
|
conn := c.clientConnTransportSnapshot()
|
|
if conn == nil {
|
|
return
|
|
}
|
|
_ = conn.Close()
|
|
return
|
|
}
|
|
logical.closeTransport()
|
|
}
|
|
|
|
func (c *ClientConn) clientConnTransportBindingSnapshot() *transportBinding {
|
|
logical := c.LogicalConn()
|
|
if logical == nil {
|
|
rt := c.clientConnSessionRuntimeSnapshot()
|
|
if rt == nil {
|
|
return nil
|
|
}
|
|
if rt.transport != nil {
|
|
return rt.transport
|
|
}
|
|
if rt.tuConn == nil {
|
|
return nil
|
|
}
|
|
return newTransportBinding(rt.tuConn, nil)
|
|
}
|
|
return logical.transportBindingSnapshot()
|
|
}
|
|
|
|
func normalizeClientConnSessionRuntimeTransportState(rt *clientConnSessionRuntime) {
|
|
if rt == nil {
|
|
return
|
|
}
|
|
if rt.transport != nil {
|
|
rt.transportAttached = rt.transport.connSnapshot() != nil
|
|
return
|
|
}
|
|
rt.transportAttached = rt.tuConn != nil
|
|
}
|
|
|
|
func ensureClientConnSessionRuntimeTransportLifecycle(rt *clientConnSessionRuntime) {
|
|
if rt == nil {
|
|
return
|
|
}
|
|
if rt.tuConn == nil {
|
|
rt.transportStopCtx = nil
|
|
rt.transportStopFn = nil
|
|
rt.transportDone = nil
|
|
return
|
|
}
|
|
if rt.transportStopCtx != nil && rt.transportStopFn != nil {
|
|
return
|
|
}
|
|
parent := rt.stopCtx
|
|
if parent == nil {
|
|
parent = context.Background()
|
|
}
|
|
rt.transportStopCtx, rt.transportStopFn = context.WithCancel(parent)
|
|
}
|
|
|
|
func ensureClientConnSessionRuntimeTransportDone(rt *clientConnSessionRuntime) {
|
|
if rt == nil {
|
|
return
|
|
}
|
|
if rt.tuConn == nil {
|
|
rt.transportDone = nil
|
|
return
|
|
}
|
|
if rt.transportDone != nil {
|
|
return
|
|
}
|
|
rt.transportDone = make(chan struct{})
|
|
}
|
|
|
|
func closeClientConnSessionRuntimeTransportDone(rt *clientConnSessionRuntime) {
|
|
if rt == nil || rt.transportDone == nil {
|
|
return
|
|
}
|
|
select {
|
|
case <-rt.transportDone:
|
|
return
|
|
default:
|
|
close(rt.transportDone)
|
|
}
|
|
}
|
|
|
|
func (c *ClientConn) clientConnTransportStopContextSnapshot() context.Context {
|
|
logical := c.LogicalConn()
|
|
if logical == nil {
|
|
rt := c.clientConnSessionRuntimeSnapshot()
|
|
if rt == nil {
|
|
return nil
|
|
}
|
|
if rt.transportStopCtx != nil {
|
|
return rt.transportStopCtx
|
|
}
|
|
return rt.stopCtx
|
|
}
|
|
return logical.transportStopContextSnapshot()
|
|
}
|
|
|
|
func (c *ClientConn) clientConnTransportAttachedSnapshot() bool {
|
|
logical := c.LogicalConn()
|
|
if logical == nil {
|
|
rt := c.clientConnSessionRuntimeSnapshot()
|
|
if rt == nil {
|
|
return false
|
|
}
|
|
return rt.transportAttached
|
|
}
|
|
return logical.transportAttachedSnapshot()
|
|
}
|