Skip to content

Commit

Permalink
perf: change ping library
Browse files Browse the repository at this point in the history
thread-safe, less memory, more fast
  • Loading branch information
macrat committed Apr 30, 2021
1 parent b4b2059 commit 77892b4
Show file tree
Hide file tree
Showing 7 changed files with 70 additions and 94 deletions.
4 changes: 1 addition & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ module github.com/macrat/ayd
go 1.16

require (
github.com/go-ping/ping v0.0.0-20210407214646-e4e642a95741
github.com/macrat/go-parallel-pinger v1.0.0
github.com/robfig/cron/v3 v3.0.1
golang.org/x/net v0.0.0-20210420210106-798c2154c571 // indirect
golang.org/x/sys v0.0.0-20210420205809-ac73e9fd8988 // indirect
)
21 changes: 6 additions & 15 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,21 +1,12 @@
github.com/go-ping/ping v0.0.0-20210407214646-e4e642a95741 h1:b0sLP++Tsle+s57tqg5sUk1/OQsC6yMCciVeqNzOcwU=
github.com/go-ping/ping v0.0.0-20210407214646-e4e642a95741/go.mod h1:35JbSyV/BYqHwwRA6Zr1uVDm1637YlNOU61wI797NPI=
github.com/macrat/go-parallel-pinger v1.0.0 h1:khn5TQ0675xQ3k80Gy7c/T9WT6610YLnLb0tA1bsD7w=
github.com/macrat/go-parallel-pinger v1.0.0/go.mod h1:s1SWsfXF4LhJmCcnD1P7eTqguyc69yhUzCWDXj8r+VE=
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20200904194848-62affa334b73/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20210420210106-798c2154c571 h1:Q6Bg8xzKzpFPU4Oi1sBnBTHBwlMsLeEXpu4hYBY8rAg=
golang.org/x/net v0.0.0-20210420210106-798c2154c571/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781 h1:DzZ89McO9/gWPsQXS/FVKAlG02ZjaQ6AlZRBimEYOd0=
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210420205809-ac73e9fd8988 h1:EjgCl+fVlIaPJSori0ikSz3uV0DOHKWOJFpv1sAAhBM=
golang.org/x/sys v0.0.0-20210420205809-ac73e9fd8988/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da h1:b3NXsE2LusjYGGjL5bxEVZZORm/YEFFrWFjR8eFrw/c=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
14 changes: 14 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,18 @@ func Usage() {
})
}

func StartProbeServer(ctx context.Context, tasks []Task) {
for _, task := range tasks {
if task.Probe.Target().Scheme == "ping" {
if err := probe.StartPinger(ctx); err != nil {
fmt.Fprintf(os.Stderr, "failed to start ping service: %s\n", err)
os.Exit(1)
}
return
}
}
}

func main() {
flag.Usage = Usage
flag.Parse()
Expand Down Expand Up @@ -89,6 +101,8 @@ func main() {
})
}

StartProbeServer(ctx, tasks)

if *oneshot {
os.Exit(RunOneshot(ctx, s, tasks))
} else {
Expand Down
87 changes: 38 additions & 49 deletions probe/ping.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,29 @@ import (
"time"

"github.com/macrat/ayd/store"
"github.com/macrat/go-parallel-pinger"
)

var (
pingerV4 *pinger.Pinger = nil
pingerV6 *pinger.Pinger = nil
)

func StartPinger(ctx context.Context) error {
pingerV4 = pinger.NewIPv4()
pingerV6 = pinger.NewIPv6()

if err := pingerV4.Start(ctx); err != nil {
return err
}

if err := pingerV6.Start(ctx); err != nil {
return err
}

return nil
}

type PingProbe struct {
target *url.URL
}
Expand All @@ -30,73 +51,41 @@ func (p PingProbe) Check(ctx context.Context, r Reporter) {
ctx, cancel := context.WithTimeout(ctx, 10*time.Second)
defer cancel()

pinger, err := getPinger(p.target.Opaque)
target, err := net.ResolveIPAddr("ip", p.target.Opaque)
if err != nil {
status := store.STATUS_FAILURE

if e, ok := err.(*net.DNSError); ok && e.IsNotFound {
status = store.STATUS_UNKNOWN
}

r.Report(store.Record{
CheckedAt: time.Now(),
Target: p.target,
Status: status,
Status: store.STATUS_UNKNOWN,
Message: err.Error(),
})
return
}

pinger.Interval = 500 * time.Millisecond
pinger.Timeout = 10 * time.Second
pinger.Count = 4
pinger.Debug = true

go func() {
<-ctx.Done()
pinger.Stop()
}()

startTime := time.Now()

err = pinger.Run()
if err != nil {
r.Report(store.Record{
CheckedAt: startTime,
Target: p.target,
Status: store.STATUS_UNKNOWN,
Message: err.Error(),
Latency: time.Now().Sub(time.Now()),
})
return
ping := pingerV4
if target.IP.To4() == nil {
ping = pingerV6
}

stat := pinger.Statistics()
startTime := time.Now()
result, err := ping.Ping(ctx, target, 4, 500*time.Millisecond)

status := store.STATUS_FAILURE
if stat.PacketLoss == 0 {
if result.Loss == 0 {
status = store.STATUS_HEALTHY
}

var message string
select {
case <-ctx.Done():
default:
message = fmt.Sprintf(
"rtt(min/avg/max)=%.2f/%.2f/%.2f send/rcv=%d/%d",
float64(stat.MinRtt.Microseconds())/1000,
float64(stat.AvgRtt.Microseconds())/1000,
float64(stat.MaxRtt.Microseconds())/1000,
pinger.PacketsSent,
pinger.PacketsRecv,
)
}

r.Report(timeoutOr(ctx, store.Record{
CheckedAt: startTime,
Target: p.target,
Status: status,
Message: message,
Latency: stat.AvgRtt,
Message: fmt.Sprintf(
"rtt(min/avg/max)=%.2f/%.2f/%.2f send/rcv=%d/%d",
float64(result.MinRTT.Microseconds())/1000,
float64(result.AvgRTT.Microseconds())/1000,
float64(result.MaxRTT.Microseconds())/1000,
result.Sent,
result.Recv,
),
Latency: result.AvgRTT,
}))
}
11 changes: 0 additions & 11 deletions probe/ping_otheros.go

This file was deleted.

11 changes: 11 additions & 0 deletions probe/ping_test.go
Original file line number Diff line number Diff line change
@@ -1,16 +1,27 @@
package probe_test

import (
"context"
"testing"

"github.com/macrat/ayd/probe"
"github.com/macrat/ayd/store"
)

func TestPingProbe(t *testing.T) {
t.Parallel()

ctx, cancel := context.WithCancel(context.Background())
defer cancel()

if err := probe.StartPinger(ctx); err != nil {
t.Fatalf("failed to start pinger: %s", err)
}

AssertProbe(t, []ProbeTest{
{"ping:localhost", store.STATUS_HEALTHY, `rtt\(min/avg/max\)=[0-9.]*/[0-9.]*/[0-9.]* send/rcv=4/4`},
{"ping:127.0.0.1", store.STATUS_HEALTHY, `rtt\(min/avg/max\)=[0-9.]*/[0-9.]*/[0-9.]* send/rcv=4/4`},
{"ping:::1", store.STATUS_HEALTHY, `rtt\(min/avg/max\)=[0-9.]*/[0-9.]*/[0-9.]* send/rcv=4/4`},
})

AssertTimeout(t, "ping:localhost")
Expand Down
16 changes: 0 additions & 16 deletions probe/ping_windows.go

This file was deleted.

0 comments on commit 77892b4

Please sign in to comment.