Skip to content

Commit

Permalink
Concurrent tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Kashkovsky committed Apr 14, 2022
1 parent 6aea67e commit 078a0e9
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 38 deletions.
40 changes: 19 additions & 21 deletions cmd/watch.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,15 @@ import (
"log"
"net/url"
"strings"
"time"
"sync"

"github.com/Kashkovsky/hostmonitor/core"
"github.com/spf13/cobra"
)

type WatchConfig struct {
configUrl string
testInterval int64
testInterval int
requestTimeout int
}

Expand All @@ -49,49 +49,47 @@ var watchCmd = &cobra.Command{
func runWatch(cmd *cobra.Command, args []string) {
log.Default().Println("Testing URLs from config ", watchConfig.configUrl)
printer := core.NewPrinter()
res := sync.Map{}

c, _, err := doWatch()
if err != nil {
log.Fatalf("Fatal: %v", err)
return
}

for {
res, err := doWatch()
if err != nil {
log.Fatalf("Fatal: %v", err)
return
}
rec := <-c
res.Store(rec.Id, rec)
printer.ToTable(&res)
time.Sleep(time.Duration(watchConfig.testInterval) * time.Second)
}
}

func doWatch() ([]core.TestResult, error) {
func doWatch() (chan core.TestResult, int, error) {
config, err := core.GetStringFromURL(watchConfig.configUrl)
outC := make(chan core.TestResult, 50)
if err != nil {
log.Fatalf("Could not obtain a config: %v", err.Error())
return []core.TestResult{}, err

return outC, 0, err
}

records := strings.Split(config, "\n")
outC := make(chan core.TestResult, 50)
for _, addr := range records {
u, err := url.Parse(addr)
if err != nil {
log.Default().Printf("Invalid url: %v, skipping...", addr)
continue
}

go core.Test(u, watchConfig.requestTimeout, outC)
go core.Test(u, watchConfig.requestTimeout, watchConfig.testInterval, outC)
}

results := []core.TestResult{}

for {
results = append(results, <-outC)
if len(results) == len(records) {
return results, nil
}
}
return outC, len(records), nil
}

func init() {
rootCmd.AddCommand(watchCmd)
watchCmd.Flags().StringVarP(&watchConfig.configUrl, "configUrl", "c", core.ITArmyConfigURL, "Url of config containing url list")
watchCmd.Flags().Int64VarP(&watchConfig.testInterval, "testInterval", "i", 10, "Interval in seconds between test updates")
watchCmd.Flags().IntVarP(&watchConfig.testInterval, "testInterval", "i", 10, "Interval in seconds between test updates")
watchCmd.Flags().IntVarP(&watchConfig.requestTimeout, "requestTimeout", "t", 5, "Request timeout")
}
28 changes: 18 additions & 10 deletions core/printer.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@ import (
"os/exec"
"runtime"
"strconv"
"sync"

"github.com/jedib0t/go-pretty/v6/table"
)

type Printer struct {
clearFns map[string]func()
t table.Writer
}

func NewPrinter() Printer {
Expand All @@ -26,21 +28,27 @@ func NewPrinter() Printer {
cmd.Run()
}

return Printer{clearFns: clear}
}

func (p *Printer) ToTable(results *[]TestResult) {
p.Clear()
t := table.NewWriter()
t.SetStyle(table.StyleColoredBright)
t.SetOutputMirror(os.Stdout)
t.AppendHeader(table.Row{"Address", "Connection", "Status"})
for _, r := range *results {
t.AppendRow(table.Row{r.url.Host, strconv.FormatInt(r.duration.Milliseconds(), 10) + "ms", r.status})
}

t.AppendSeparator()
t.Render()
return Printer{clearFns: clear, t: t}
}

func (p *Printer) ToTable(results *sync.Map) {
p.Clear()
p.t.ResetRows()
results.Range(func(k any, r interface{}) bool {
testResult, ok := r.(TestResult)
if ok {
p.t.AppendRow(table.Row{k, strconv.FormatInt(testResult.duration.Milliseconds(), 10) + "ms", testResult.status})
}
return true
})
p.t.SortBy([]table.SortBy{{Name: "Address"}})
p.t.AppendSeparator()
p.t.Render()
}

func (p *Printer) Clear() {
Expand Down
21 changes: 14 additions & 7 deletions core/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,23 +35,30 @@ func GetStringFromURL(url string) (string, error) {
}

type TestResult struct {
Id string
url url.URL
status string
duration time.Duration
}

func Test(url *url.URL, timeoutSeconds int, out chan TestResult) {
func Test(url *url.URL, timeoutSeconds int, testInterval int, out chan TestResult) {
timeout := time.Duration(timeoutSeconds) * time.Second
tp := NewTransport(timeout)

_, err := tp.Dial(url.Scheme, url.Host)
for {
out <- TestResult{Id: url.Host, url: *url, status: "Test"}

if err != nil {
out <- TestResult{url: *url, status: formatError(err, url), duration: tp.ConnDuration()}
return
}
_, err := tp.Dial(url.Scheme, url.Host)

if err != nil {
out <- TestResult{Id: url.Host, url: *url, status: formatError(err, url), duration: tp.ConnDuration()}
return
}

out <- TestResult{url: *url, status: "OK", duration: tp.Duration()}
out <- TestResult{Id: url.Host, url: *url, status: "OK", duration: tp.Duration()}
time.Sleep(time.Duration(testInterval) * time.Second)

}
}

func formatError(err error, url *url.URL) string {
Expand Down
Binary file modified monitor
Binary file not shown.

0 comments on commit 078a0e9

Please sign in to comment.