From d9b3de60e507868abde668c091a215ed27d632f3 Mon Sep 17 00:00:00 2001 From: Artyom Egorov Date: Tue, 9 Apr 2024 04:57:27 +0700 Subject: [PATCH] parallel requests --- pkg/ping/arguments.go | 2 +- pkg/ping/net.go | 44 +++++++++++++++++++++++++++--------- wowPing.go | 52 ++++++++++++++++++++++--------------------- 3 files changed, 62 insertions(+), 36 deletions(-) diff --git a/pkg/ping/arguments.go b/pkg/ping/arguments.go index 2006b9d..505bd70 100644 --- a/pkg/ping/arguments.go +++ b/pkg/ping/arguments.go @@ -5,7 +5,7 @@ import ( "strings" ) -const REQUEST_COUNT = 4 +const REQUEST_COUNT = 6 const TIMEOUT = 1000 const SERVER_GROUP = "x1" diff --git a/pkg/ping/net.go b/pkg/ping/net.go index f1f80df..db9a6ef 100644 --- a/pkg/ping/net.go +++ b/pkg/ping/net.go @@ -12,34 +12,58 @@ import ( var ErrInvalidResponse = errors.New("invalid response") -func OpenConnection(host string, port, timeout int) (int, error) { +type ServerResponse struct { + Name string + Duration int + Error error +} + +func OpenConnection(name, host string, port, timeout int, respose chan<- ServerResponse) { address := fmt.Sprintf("%v:%v", host, port) conn, err := net.DialTimeout("tcp", address, time.Millisecond*time.Duration(timeout)) - connectTime := time.Now() if err != nil { - return 0, err + respose <- ServerResponse{ + Name: name, + Error: err, + } + return } defer conn.Close() buf := make([]byte, 4) - conn.SetDeadline(connectTime.Add(time.Millisecond * time.Duration(timeout))) + conn.SetDeadline(time.Now().Add(time.Millisecond * time.Duration(timeout))) + connectTime := time.Now() _, err = conn.Read(buf) - responseTime := time.Now() + duration := time.Since(connectTime) if err != nil && err != io.EOF { - return 0, err + respose <- ServerResponse{ + Name: name, + Error: err, + } + return } var opcode uint16 reader := bytes.NewReader(buf[2:4]) err = binary.Read(reader, binary.LittleEndian, &opcode) if err != nil { - return 0, err + respose <- ServerResponse{ + Name: name, + Error: err, + } + return } if opcode != SMSG_AUTH_CHALLENGE { - return 0, ErrInvalidResponse + respose <- ServerResponse{ + Name: name, + Error: ErrInvalidResponse, + } + return } - res := responseTime.Sub(connectTime).Milliseconds() - return int(res), nil + respose <- ServerResponse{ + Name: name, + Duration: int(duration.Milliseconds()), + } } diff --git a/wowPing.go b/wowPing.go index 4dd886a..784240d 100644 --- a/wowPing.go +++ b/wowPing.go @@ -17,46 +17,48 @@ func main() { fmt.Printf("Timeout %v ms\n", params.Timeout) fmt.Printf("Server group '%v'\n", params.ServerGroup) statistics := make(map[string]ping.Statistics) - - for _, group := range ping.Servers { - if group.Name != params.ServerGroup { - continue - } - for _, server := range group.List { - statistics[server.Name] = ping.Statistics{ - ServerName: server.Name, - } - } - } + responseChan := make(chan ping.ServerResponse) for i := 0; i < params.RequestCount; i++ { fmt.Println("") fmt.Printf("Request # %v\n", i+1) + connectionCount := 0 for _, group := range ping.Servers { if group.Name != params.ServerGroup { continue } + for _, server := range group.List { - stat := statistics[server.Name] + connectionCount++ + go ping.OpenConnection(server.Name, server.Host, server.Port, params.Timeout, responseChan) + } + } - responseTime, err := ping.OpenConnection(server.Host, server.Port, params.Timeout) + for i := 0; i < connectionCount; i++ { + response := <-responseChan - if err == nil { - stat.ResponseDurations = append(stat.ResponseDurations, responseTime) - fmt.Printf("%v %vms\n", server.Name, responseTime) - } else { - if errors.Is(err, context.DeadlineExceeded) || errors.Is(err, os.ErrDeadlineExceeded) { - stat.Timeouts++ - fmt.Println(server.Name, "timeout") - } else { - stat.Errors++ - fmt.Println(server.Name, err) - } + stat, statExist := statistics[response.Name] + if !statExist { + stat = ping.Statistics{ + ServerName: response.Name, } + } - statistics[server.Name] = stat + if response.Error == nil { + stat.ResponseDurations = append(stat.ResponseDurations, response.Duration) + fmt.Printf("%v %vms\n", response.Name, response.Duration) + } else { + if errors.Is(response.Error, context.DeadlineExceeded) || errors.Is(response.Error, os.ErrDeadlineExceeded) { + stat.Timeouts++ + fmt.Println(response.Name, "timeout") + } else { + stat.Errors++ + fmt.Println(response.Name, response.Error) + } } + + statistics[response.Name] = stat } }