package mesh import ( "context" "fmt" "time" "github.com/example/remote-access-platform/agents/rap-node-agent/internal/fabricproto" ) func ProbeFabricTarget(ctx context.Context, target FabricTransportTarget) (time.Duration, error) { target.Timeout = positiveDurationOr(target.Timeout, 2*time.Second) target.InboundBuffer = positiveIntOr(target.InboundBuffer, 2) target.ErrorBuffer = positiveIntOr(target.ErrorBuffer, 2) transport, normalizedTarget, err := FabricTransportForTarget(target, nil) if err != nil { return 0, err } session, err := transport.Connect(ctx, normalizedTarget) if err != nil { _ = transport.Close() return 0, err } defer func() { _ = session.Close() _ = transport.Close() }() startedAt := time.Now() sequence := uint64(startedAt.UnixNano()) if err := session.Send(ctx, fabricproto.Frame{ Type: fabricproto.FramePing, TrafficClass: fabricproto.TrafficClassReliable, Sequence: sequence, Payload: []byte("fabric-live-probe"), }); err != nil { return 0, err } for { select { case frame, ok := <-session.Frames(): if !ok { return 0, fmt.Errorf("fabric live probe session closed") } if frame.Type == fabricproto.FramePong && frame.Sequence == sequence { return time.Since(startedAt), nil } case err, ok := <-session.Errors(): if !ok { return 0, fmt.Errorf("fabric live probe error channel closed") } if err != nil { return 0, err } case <-ctx.Done(): return 0, ctx.Err() } } } func positiveDurationOr(value time.Duration, fallback time.Duration) time.Duration { if value > 0 { return value } return fallback } func positiveIntOr(value int, fallback int) int { if value > 0 { return value } return fallback }