0

I am trying to make a GO application that is able to ping multiple adresses at the same time. I have followed multiple tutorials and codeparts and now I have been stuck on this part for some time.

I have tried using channels however that did not bring me any further. This is my first time working with routines and I am new in Go.

package main

import (
    "database/sql"
    "fmt"
    _ "github.com/go-sql-driver/mysql"
    "github.com/tatsushid/go-fastping"
    "log"
    "net"
    "os"
    "sync"
    "time"
)

var (
    id int
    ip string
)

var rttr time.Duration
var db *sql.DB

var wg sync.WaitGroup


func main() {
    for {
        queries := []string{
            "SELECT id, ip FROM hosts where id < 50",
            "SELECT id, ip FROM hosts where id >= 50",
        }


        for _, query := range queries {
            wg.Add(1)
            go doPing(query)
        }
        wg.Wait()
    }
}

func doPing(query string) {
    defer wg.Done()


    fmt.Println("Worker started!")
    time.Sleep(time.Second)

    db, err := sql.Open("mysql", "Your credentials :) ")
    if err != nil {
        panic(err)
    }

    db.SetConnMaxLifetime(time.Minute * 15)
    db.SetMaxOpenConns(10)
    db.SetMaxIdleConns(10)
    rows, err := db.Query(query)

    fmt.Println("QUERY:")
    fmt.Println(query)
    fmt.Println("--------")
    if err != nil {
        log.Fatal(err)
    }
    defer rows.Close()
    for rows.Next() {
        err := rows.Scan(&id, &ip)
        if err != nil {
            log.Fatal(err)
        }
        p := fastping.NewPinger()
        ra, err := net.ResolveIPAddr("ip4:icmp", ip)
        if err != nil {
            fmt.Println(err)
            os.Exit(1)
        }
        p.AddIPAddr(ra)
        p.OnRecv = func(addr *net.IPAddr, rtt time.Duration) {
            fmt.Printf("IP Addr: %s receive, RTT: %v\n", addr.String(), rtt)
            fmt.Println(id)
            rttr = rtt
        }
        p.OnIdle = func() {
            *irrelevant database stuff, ignore*
        }
        err = p.Run()
        if err != nil {
            fmt.Println(err)
        }
        time.Sleep(time.Second)

    }
}

Console output

I am also new in making questions so if you need anything, lmk :)

  • 3
    You have a data race regarding `id`, `ip`, `rttr` and `db`: declare these variables in `doPing()` instead of globally. Otherwise, your two go routines will overwrite each others' changes to them. See also compiling with the `--race` switch. – Zyl Oct 25 '21 at 13:34
  • Now that you say it... Explains alot! And it works now! Thanks! – Christiaan Oct 25 '21 at 13:42

0 Answers0