75 lines
1.7 KiB
Go
75 lines
1.7 KiB
Go
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
|
|
}
|