@@ -71,42 +71,67 @@ func (p *PingService) PingHandler(s inet.Stream) {
71
71
}
72
72
}
73
73
74
- func (ps * PingService ) Ping (ctx context.Context , p peer.ID ) (<- chan time.Duration , error ) {
74
+ // Result is a result of a ping attempt, either an RTT or an error.
75
+ type Result struct {
76
+ RTT time.Duration
77
+ Error error
78
+ }
79
+
80
+ func (ps * PingService ) Ping (ctx context.Context , p peer.ID ) <- chan Result {
75
81
return Ping (ctx , ps .Host , p )
76
82
}
77
83
78
- func Ping (ctx context.Context , h host.Host , p peer.ID ) (<- chan time.Duration , error ) {
84
+ // Ping pings the remote peer until the context is canceled, returning a stream
85
+ // of RTTs or errors.
86
+ func Ping (ctx context.Context , h host.Host , p peer.ID ) <- chan Result {
79
87
s , err := h .NewStream (ctx , p , ID )
80
88
if err != nil {
81
- return nil , err
89
+ ch := make (chan Result , 1 )
90
+ ch <- Result {Error : err }
91
+ close (ch )
92
+ return ch
82
93
}
83
94
84
- out := make (chan time.Duration )
95
+ ctx , cancel := context .WithCancel (ctx )
96
+
97
+ out := make (chan Result )
85
98
go func () {
86
99
defer close (out )
87
- defer s .Reset ()
100
+ defer cancel ()
101
+
88
102
for {
89
103
select {
90
104
case <- ctx .Done ():
91
105
return
92
106
default :
93
- t , err := ping (s )
94
- if err != nil {
95
- log .Debugf ("ping error: %s" , err )
107
+ var res Result
108
+ res .RTT , res .Error = ping (s )
109
+
110
+ // canceled, ignore everything.
111
+ if ctx .Err () != nil {
96
112
return
97
113
}
98
114
99
- h .Peerstore ().RecordLatency (p , t )
115
+ // No error, record the RTT.
116
+ if res .Error == nil {
117
+ h .Peerstore ().RecordLatency (p , res .RTT )
118
+ }
119
+
100
120
select {
101
- case out <- t :
121
+ case out <- res :
102
122
case <- ctx .Done ():
103
123
return
104
124
}
105
125
}
106
126
}
107
127
}()
128
+ go func () {
129
+ // forces the ping to abort.
130
+ <- ctx .Done ()
131
+ s .Reset ()
132
+ }()
108
133
109
- return out , nil
134
+ return out
110
135
}
111
136
112
137
func ping (s inet.Stream ) (time.Duration , error ) {
0 commit comments