1
0
mirror of https://github.com/taigrr/go-fastping synced 2025-01-18 05:03:15 -08:00

Refactor RunLoop() and change its usage

This commit is contained in:
Tatsushi Demachi 2014-08-03 17:36:03 +09:00
parent 8187842419
commit d1ac219a65
3 changed files with 27 additions and 22 deletions

View File

@ -40,7 +40,7 @@ func main() {
}) })
p.MaxRTT = time.Second p.MaxRTT = time.Second
errch := p.RunLoop() p.RunLoop()
c := make(chan os.Signal, 1) c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt) signal.Notify(c, os.Interrupt)
@ -65,8 +65,10 @@ loop:
} }
results[host] = nil results[host] = nil
} }
case err := <-errch: case <-p.Done():
fmt.Println("Ping failed: %v", err) if err = p.Err(); err != nil {
fmt.Println("Ping failed:", err)
}
break loop break loop
} }
} }

View File

@ -87,7 +87,6 @@ type Pinger struct {
// key string is IPAddr.String() // key string is IPAddr.String()
addrs map[string]*net.IPAddr addrs map[string]*net.IPAddr
ctx *context ctx *context
running bool
// Number of (nano,milli)seconds of an idle timeout. Once it passed, // Number of (nano,milli)seconds of an idle timeout. Once it passed,
// the library calls an idle callback function. It is also used for an // the library calls an idle callback function. It is also used for an
// interval time of RunLoop() method // interval time of RunLoop() method
@ -104,7 +103,6 @@ func NewPinger() *Pinger {
id: rand.Intn(0xffff), id: rand.Intn(0xffff),
seq: rand.Intn(0xffff), seq: rand.Intn(0xffff),
addrs: make(map[string]*net.IPAddr), addrs: make(map[string]*net.IPAddr),
running: false,
MaxRTT: time.Second, MaxRTT: time.Second,
handlers: make(map[string]interface{}), handlers: make(map[string]interface{}),
Debug: false, Debug: false,
@ -180,14 +178,16 @@ func (p *Pinger) Run() error {
// After MaxRTT seconds, it calls "idle" handler, resend packets and wait those // After MaxRTT seconds, it calls "idle" handler, resend packets and wait those
// response. MaxRTT works as an interval time. // response. MaxRTT works as an interval time.
// //
// This is a non-blocking method so immediately returns with channel value. // This is a non-blocking method so immediately returns. If you want to monitor
// If you want to stop sending packets, use Stop(). For example, // and stop sending packets, use Done() and Stop() method. For example,
// //
// errch := p.RunLoop() // p.RunLoop()
// ticker := time.NewTicker(time.Millisecond * 250) // ticker := time.NewTicker(time.Millisecond * 250)
// select { // select {
// case err := <-errch: // case <-p.Done():
// log.Fatalf("Ping failed: %v", err) // if err := p.Err(); err != nil {
// log.Fatalf("Ping failed: %v", err)
// }
// case <-ticker.C: // case <-ticker.C:
// break // break
// } // }
@ -195,16 +195,13 @@ func (p *Pinger) Run() error {
// p.Stop() // p.Stop()
// //
// For more detail, please see "cmd/ping/ping.go". // For more detail, please see "cmd/ping/ping.go".
func (p *Pinger) RunLoop() <-chan error { func (p *Pinger) RunLoop() {
p.ctx = newContext() p.ctx = newContext()
errch := make(chan error) go p.run(false)
go func(ch chan<- error) { }
p.run(false)
if p.ctx.err != nil { func (p *Pinger) Done() <-chan bool {
ch <- p.ctx.err return p.ctx.done
}
}(errch)
return errch
} }
func (p *Pinger) Stop() { func (p *Pinger) Stop() {
@ -214,6 +211,10 @@ func (p *Pinger) Stop() {
<-p.ctx.done <-p.ctx.done
} }
func (p *Pinger) Err() error {
return p.ctx.err
}
func (p *Pinger) run(once bool) { func (p *Pinger) run(once bool) {
p.debugln("Run(): Start") p.debugln("Run(): Start")
conn, err := net.ListenIP("ip4:icmp", &net.IPAddr{IP: net.IPv4zero}) conn, err := net.ListenIP("ip4:icmp", &net.IPAddr{IP: net.IPv4zero})

View File

@ -199,11 +199,13 @@ func TestRunLoop(t *testing.T) {
t.Fatalf("Failed to add idle handler: %v", err) t.Fatalf("Failed to add idle handler: %v", err)
} }
errch := p.RunLoop() p.RunLoop()
ticker := time.NewTicker(time.Millisecond * 250) ticker := time.NewTicker(time.Millisecond * 250)
select { select {
case err := <-errch: case <-p.Done():
t.Fatalf("Pinger returns error %v", err) if err = p.Err(); err != nil {
t.Fatalf("Pinger returns error %v", err)
}
case <-ticker.C: case <-ticker.C:
break break
} }