notify/file_transfer_public.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

284 lines
10 KiB
Go

package notify
import (
"errors"
"time"
)
type FileTransferSummary struct {
Direction TransferDirection
Scope string
RuntimeScope string
TransportGeneration uint64
NetType NetType
Kind EnvelopeKind
FileID string
Path string
Received int64
Total int64
Percent float64
Active bool
Terminal bool
Done bool
Failed bool
Err error
StartedAt time.Time
UpdatedAt time.Time
Duration time.Duration
RateBPS float64
StepDuration time.Duration
InstantRateBPS float64
Time time.Time
Stage string
}
type FileTransferSummaryGroup struct {
Send []FileTransferSummary
Receive []FileTransferSummary
}
type FileTransferSummaryQuery struct {
Scope string
RuntimeScope string
TransportGeneration uint64
MatchTransportGeneration bool
}
type clientFileTransferSummaryReader interface {
clientFileTransferActiveSummaries() FileTransferSummaryGroup
clientFileTransferCompletedSummaries() FileTransferSummaryGroup
clientFileTransferFailedSummaries() FileTransferSummaryGroup
clientFileTransferLatestByFileID(string) FileTransferSummaryGroup
clientFileTransferLatestByFileIDQuery(string, FileTransferSummaryQuery) FileTransferSummaryGroup
}
type serverFileTransferSummaryReader interface {
serverFileTransferActiveSummaries() FileTransferSummaryGroup
serverFileTransferCompletedSummaries() FileTransferSummaryGroup
serverFileTransferFailedSummaries() FileTransferSummaryGroup
serverFileTransferLatestByFileID(string) FileTransferSummaryGroup
serverFileTransferLatestByFileIDQuery(string, FileTransferSummaryQuery) FileTransferSummaryGroup
}
var (
errClientFileTransferSummaryNil = errors.New("client file transfer summary target is nil")
errServerFileTransferSummaryNil = errors.New("server file transfer summary target is nil")
errClientFileTransferSummaryUnsupported = errors.New("client file transfer summary target type is unsupported")
errServerFileTransferSummaryUnsupported = errors.New("server file transfer summary target type is unsupported")
)
func GetClientFileTransferActiveSummaries(c Client) (FileTransferSummaryGroup, error) {
if c == nil {
return FileTransferSummaryGroup{}, errClientFileTransferSummaryNil
}
reader, ok := any(c).(clientFileTransferSummaryReader)
if !ok {
return FileTransferSummaryGroup{}, errClientFileTransferSummaryUnsupported
}
return reader.clientFileTransferActiveSummaries(), nil
}
func GetServerFileTransferActiveSummaries(s Server) (FileTransferSummaryGroup, error) {
if s == nil {
return FileTransferSummaryGroup{}, errServerFileTransferSummaryNil
}
reader, ok := any(s).(serverFileTransferSummaryReader)
if !ok {
return FileTransferSummaryGroup{}, errServerFileTransferSummaryUnsupported
}
return reader.serverFileTransferActiveSummaries(), nil
}
func GetClientFileTransferCompletedSummaries(c Client) (FileTransferSummaryGroup, error) {
if c == nil {
return FileTransferSummaryGroup{}, errClientFileTransferSummaryNil
}
reader, ok := any(c).(clientFileTransferSummaryReader)
if !ok {
return FileTransferSummaryGroup{}, errClientFileTransferSummaryUnsupported
}
return reader.clientFileTransferCompletedSummaries(), nil
}
func GetServerFileTransferCompletedSummaries(s Server) (FileTransferSummaryGroup, error) {
if s == nil {
return FileTransferSummaryGroup{}, errServerFileTransferSummaryNil
}
reader, ok := any(s).(serverFileTransferSummaryReader)
if !ok {
return FileTransferSummaryGroup{}, errServerFileTransferSummaryUnsupported
}
return reader.serverFileTransferCompletedSummaries(), nil
}
func GetClientFileTransferFailedSummaries(c Client) (FileTransferSummaryGroup, error) {
if c == nil {
return FileTransferSummaryGroup{}, errClientFileTransferSummaryNil
}
reader, ok := any(c).(clientFileTransferSummaryReader)
if !ok {
return FileTransferSummaryGroup{}, errClientFileTransferSummaryUnsupported
}
return reader.clientFileTransferFailedSummaries(), nil
}
func GetServerFileTransferFailedSummaries(s Server) (FileTransferSummaryGroup, error) {
if s == nil {
return FileTransferSummaryGroup{}, errServerFileTransferSummaryNil
}
reader, ok := any(s).(serverFileTransferSummaryReader)
if !ok {
return FileTransferSummaryGroup{}, errServerFileTransferSummaryUnsupported
}
return reader.serverFileTransferFailedSummaries(), nil
}
func GetClientFileTransferLatestByFileID(c Client, fileID string) (FileTransferSummaryGroup, error) {
if c == nil {
return FileTransferSummaryGroup{}, errClientFileTransferSummaryNil
}
reader, ok := any(c).(clientFileTransferSummaryReader)
if !ok {
return FileTransferSummaryGroup{}, errClientFileTransferSummaryUnsupported
}
return reader.clientFileTransferLatestByFileID(fileID), nil
}
func GetServerFileTransferLatestByFileID(s Server, fileID string) (FileTransferSummaryGroup, error) {
if s == nil {
return FileTransferSummaryGroup{}, errServerFileTransferSummaryNil
}
reader, ok := any(s).(serverFileTransferSummaryReader)
if !ok {
return FileTransferSummaryGroup{}, errServerFileTransferSummaryUnsupported
}
return reader.serverFileTransferLatestByFileID(fileID), nil
}
func GetClientFileTransferLatestByFileIDQuery(c Client, fileID string, query FileTransferSummaryQuery) (FileTransferSummaryGroup, error) {
if c == nil {
return FileTransferSummaryGroup{}, errClientFileTransferSummaryNil
}
reader, ok := any(c).(clientFileTransferSummaryReader)
if !ok {
return FileTransferSummaryGroup{}, errClientFileTransferSummaryUnsupported
}
return reader.clientFileTransferLatestByFileIDQuery(fileID, query), nil
}
func GetServerFileTransferLatestByFileIDQuery(s Server, fileID string, query FileTransferSummaryQuery) (FileTransferSummaryGroup, error) {
if s == nil {
return FileTransferSummaryGroup{}, errServerFileTransferSummaryNil
}
reader, ok := any(s).(serverFileTransferSummaryReader)
if !ok {
return FileTransferSummaryGroup{}, errServerFileTransferSummaryUnsupported
}
return reader.serverFileTransferLatestByFileIDQuery(fileID, query), nil
}
func (c *ClientCommon) clientFileTransferActiveSummaries() FileTransferSummaryGroup {
return publicFileTransferSummaryGroup(c.getFileTransferState().active())
}
func (c *ClientCommon) clientFileTransferCompletedSummaries() FileTransferSummaryGroup {
return publicFileTransferSummaryGroup(c.getFileTransferState().completed())
}
func (c *ClientCommon) clientFileTransferFailedSummaries() FileTransferSummaryGroup {
return publicFileTransferSummaryGroup(c.getFileTransferState().failed())
}
func (c *ClientCommon) clientFileTransferLatestByFileID(fileID string) FileTransferSummaryGroup {
return publicFileTransferSummaryGroup(c.getFileTransferState().latestByFileID(fileID))
}
func (c *ClientCommon) clientFileTransferLatestByFileIDQuery(fileID string, query FileTransferSummaryQuery) FileTransferSummaryGroup {
return publicFileTransferSummaryGroup(c.getFileTransferState().latestByFileIDQuery(fileID, internalFileTransferSummaryQuery(query)))
}
func (s *ServerCommon) serverFileTransferActiveSummaries() FileTransferSummaryGroup {
return publicFileTransferSummaryGroup(s.getFileTransferState().active())
}
func (s *ServerCommon) serverFileTransferCompletedSummaries() FileTransferSummaryGroup {
return publicFileTransferSummaryGroup(s.getFileTransferState().completed())
}
func (s *ServerCommon) serverFileTransferFailedSummaries() FileTransferSummaryGroup {
return publicFileTransferSummaryGroup(s.getFileTransferState().failed())
}
func (s *ServerCommon) serverFileTransferLatestByFileID(fileID string) FileTransferSummaryGroup {
return publicFileTransferSummaryGroup(s.getFileTransferState().latestByFileID(fileID))
}
func (s *ServerCommon) serverFileTransferLatestByFileIDQuery(fileID string, query FileTransferSummaryQuery) FileTransferSummaryGroup {
return publicFileTransferSummaryGroup(s.getFileTransferState().latestByFileIDQuery(fileID, internalFileTransferSummaryQuery(query)))
}
func publicFileTransferSummaryGroup(src fileTransferSummaryGroup) FileTransferSummaryGroup {
return FileTransferSummaryGroup{
Send: publicFileTransferSummaries(src.Send),
Receive: publicFileTransferSummaries(src.Receive),
}
}
func publicFileTransferSummaries(src []fileTransferSummary) []FileTransferSummary {
if len(src) == 0 {
return nil
}
out := make([]FileTransferSummary, 0, len(src))
for _, summary := range src {
out = append(out, publicFileTransferSummary(summary))
}
return out
}
func publicFileTransferSummary(summary fileTransferSummary) FileTransferSummary {
return FileTransferSummary{
Direction: publicFileTransferDirection(summary.Direction),
Scope: summary.Scope,
RuntimeScope: summary.RuntimeScope,
TransportGeneration: summary.TransportGeneration,
NetType: summary.NetType,
Kind: summary.Kind,
FileID: summary.FileID,
Path: summary.Path,
Received: summary.Received,
Total: summary.Total,
Percent: summary.Percent,
Active: summary.Active,
Terminal: summary.Terminal,
Done: summary.Done,
Failed: summary.Failed,
Err: summary.Err,
StartedAt: summary.StartedAt,
UpdatedAt: summary.UpdatedAt,
Duration: summary.Duration,
RateBPS: summary.RateBPS,
StepDuration: summary.StepDuration,
InstantRateBPS: summary.InstantRateBPS,
Time: summary.Time,
Stage: summary.Stage,
}
}
func publicFileTransferDirection(direction fileTransferDirection) TransferDirection {
switch direction {
case fileTransferDirectionReceive:
return TransferDirectionReceive
default:
return TransferDirectionSend
}
}
func internalFileTransferSummaryQuery(query FileTransferSummaryQuery) fileTransferSummaryQuery {
return fileTransferSummaryQuery{
Scope: query.Scope,
RuntimeScope: query.RuntimeScope,
TransportGeneration: query.TransportGeneration,
MatchTransportGeneration: query.MatchTransportGeneration,
}
}