mirror of
https://github.com/taigrr/go-fastping
synced 2025-01-18 05:03:15 -08:00
Simplify RunLoop() call and add Stop()
This commit is contained in:
parent
a97a44952e
commit
88c0127fe9
@ -40,20 +40,18 @@ func main() {
|
||||
})
|
||||
|
||||
p.MaxRTT = time.Second
|
||||
quit, errch := p.RunLoop()
|
||||
errch := p.RunLoop()
|
||||
|
||||
c := make(chan os.Signal, 1)
|
||||
signal.Notify(c, os.Interrupt)
|
||||
signal.Notify(c, syscall.SIGTERM)
|
||||
wait := make(chan bool)
|
||||
|
||||
loop:
|
||||
for {
|
||||
select {
|
||||
case <-c:
|
||||
fmt.Println("get interrupted")
|
||||
signal.Stop(c)
|
||||
quit <- wait
|
||||
break loop
|
||||
case res := <-onRecv:
|
||||
if _, ok := results[res.addr.String()]; ok {
|
||||
results[res.addr.String()] = res
|
||||
@ -69,10 +67,9 @@ loop:
|
||||
}
|
||||
case err := <-errch:
|
||||
fmt.Println("Ping failed: %v", err)
|
||||
break loop
|
||||
}
|
||||
}
|
||||
signal.Stop(c)
|
||||
quit <- wait
|
||||
case <-wait:
|
||||
break loop;
|
||||
}
|
||||
}
|
||||
p.Stop()
|
||||
}
|
||||
|
53
fastping.go
53
fastping.go
@ -72,6 +72,8 @@ type Pinger struct {
|
||||
seq int
|
||||
// key string is IPAddr.String()
|
||||
addrs map[string]*net.IPAddr
|
||||
quit chan chan<- bool
|
||||
running bool
|
||||
// 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
|
||||
// interval time of RunLoop() method
|
||||
@ -88,6 +90,7 @@ func NewPinger() *Pinger {
|
||||
id: rand.Intn(0xffff),
|
||||
seq: rand.Intn(0xffff),
|
||||
addrs: make(map[string]*net.IPAddr),
|
||||
running: false,
|
||||
MaxRTT: time.Second,
|
||||
handlers: make(map[string]interface{}),
|
||||
Debug: false,
|
||||
@ -152,7 +155,7 @@ func (p *Pinger) AddHandler(event string, handler interface{}) error {
|
||||
// an error value. It means it blocks until MaxRTT seconds passed. For the
|
||||
// purpose of sending/receiving packets over and over, use RunLoop().
|
||||
func (p *Pinger) Run() error {
|
||||
return p.run(true, make(chan chan<- bool))
|
||||
return p.run(true)
|
||||
}
|
||||
|
||||
// Invode send/receive procedure repeatedly. It sends packets to all hosts which
|
||||
@ -161,40 +164,42 @@ func (p *Pinger) Run() error {
|
||||
// After MaxRTT seconds, it calls "idle" handler, resend packets and wait those
|
||||
// response. MaxRTT works as an interval time.
|
||||
//
|
||||
// This is a non-blocking method so immediately returns with channel values.
|
||||
// If you want to stop sending packets, send a channel value of bool type to it
|
||||
// and wait for graceful shutdown. For example,
|
||||
// This is a non-blocking method so immediately returns with channel value.
|
||||
// If you want to stop sending packets, use Stop(). For example,
|
||||
//
|
||||
// wait := make(chan bool)
|
||||
// quit, errch := p.RunLoop()
|
||||
// errch := p.RunLoop()
|
||||
// ticker := time.NewTicker(time.Millisecond * 250)
|
||||
// loop:
|
||||
// for {
|
||||
// select {
|
||||
// case err := <-errch:
|
||||
// log.Fatalf("Ping failed: %v", err)
|
||||
// case <-ticker.C:
|
||||
// break
|
||||
// }
|
||||
// ticker.Stop()
|
||||
// quit <- wait
|
||||
// case <-wait:
|
||||
// break loop
|
||||
// }
|
||||
// }
|
||||
// p.Stop()
|
||||
//
|
||||
// For more detail, please see "cmd/ping/ping.go".
|
||||
func (p *Pinger) RunLoop() (chan<- chan<- bool, <-chan error) {
|
||||
quit := make(chan chan<- bool)
|
||||
func (p *Pinger) RunLoop() <-chan error {
|
||||
p.quit = make(chan chan<- bool)
|
||||
errch := make(chan error)
|
||||
go func(ch chan<- error) {
|
||||
err := p.run(false, quit)
|
||||
err := p.run(false)
|
||||
if err != nil {
|
||||
ch <- err
|
||||
}
|
||||
}(errch)
|
||||
return quit, errch
|
||||
return errch
|
||||
}
|
||||
|
||||
func (p *Pinger) run(once bool, quit <-chan chan<- bool) error {
|
||||
func (p *Pinger) Stop() {
|
||||
if p.running {
|
||||
wait := make(chan bool)
|
||||
p.quit <- wait
|
||||
<-wait
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Pinger) run(once bool) error {
|
||||
p.debugln("Run(): Start")
|
||||
conn, err := net.ListenIP("ip4:icmp", &net.IPAddr{IP: net.IPv4zero})
|
||||
if err != nil {
|
||||
@ -212,14 +217,13 @@ func (p *Pinger) run(once bool, quit <-chan chan<- bool) error {
|
||||
queue, err := p.sendICMP4(conn)
|
||||
|
||||
ticker := time.NewTicker(p.MaxRTT)
|
||||
p.running = true
|
||||
|
||||
mainloop:
|
||||
for {
|
||||
select {
|
||||
case join = <-quit:
|
||||
p.debugln("Run(): <-quit")
|
||||
p.debugln("Run(): stoprecv <- waitjoin")
|
||||
stoprecv <- waitjoin
|
||||
case join = <-p.quit:
|
||||
p.debugln("Run(): <-p.quit")
|
||||
break mainloop
|
||||
case <-ticker.C:
|
||||
if handler, ok := p.handlers["idle"]; ok && handler != nil {
|
||||
@ -228,8 +232,6 @@ mainloop:
|
||||
}
|
||||
}
|
||||
if once || err != nil {
|
||||
p.debugln("Run(): stoprecv <- waitjoin")
|
||||
stoprecv <- waitjoin
|
||||
break mainloop
|
||||
}
|
||||
p.debugln("Run(): call sendICMP4()")
|
||||
@ -240,8 +242,11 @@ mainloop:
|
||||
}
|
||||
}
|
||||
|
||||
p.running = false
|
||||
ticker.Stop()
|
||||
|
||||
p.debugln("Run(): stoprecv <- waitjoin")
|
||||
stoprecv <- waitjoin
|
||||
p.debugln("Run(): <-waitjoin")
|
||||
<-waitjoin
|
||||
if !once {
|
||||
|
@ -199,21 +199,16 @@ func TestRunLoop(t *testing.T) {
|
||||
t.Fatalf("Failed to add idle handler: %v", err)
|
||||
}
|
||||
|
||||
wait := make(chan bool)
|
||||
quit, errch := p.RunLoop()
|
||||
errch := p.RunLoop()
|
||||
ticker := time.NewTicker(time.Millisecond * 250)
|
||||
loop:
|
||||
for {
|
||||
select {
|
||||
case err := <-errch:
|
||||
t.Fatalf("Pinger returns error %v", err)
|
||||
case <-ticker.C:
|
||||
break
|
||||
}
|
||||
ticker.Stop()
|
||||
quit <- wait
|
||||
case <-wait:
|
||||
break loop
|
||||
}
|
||||
}
|
||||
p.Stop()
|
||||
|
||||
if recvCount < 2 {
|
||||
t.Fatalf("Pinger receive count less than 2")
|
||||
|
Loading…
x
Reference in New Issue
Block a user