Answer the question
In order to leave comments, you need to log in
How to properly set up a channel in Golang?
Please tell me where to fix it here, so that in the end my functions would wait for each other, main ends and the maps do not have time to fill up
package main
import (
"flag"
"fmt"
"log"
"net/http"
"strings"
"time"
)
type inputDataStruct struct {
url []string
count int
timeOut int
dataResponses map[string][]float64
noResponses map[string]int
}
func getResponse(urlChan chan string, inputData inputDataStruct) {
url := <-urlChan
start := time.Now()
client := http.Client{
Timeout: time.Duration(inputData.timeOut) * time.Second,
}
result, err := client.Get(url)
if err != nil {
inputData.noResponses[url] = inputData.noResponses[url] + 1
log.Fatal(err)
}
elapsed := time.Since(start).Seconds()
defer result.Body.Close()
s := fmt.Sprintf("%s %f", url, elapsed)
log.Println(s)
if result.StatusCode == http.StatusOK {
go appendResponse(urlChan, elapsed, inputData)
urlChan <- url
}
}
func appendResponse(urlChan chan string, time float64, inputData inputDataStruct) {
inputData.dataResponses[<-urlChan] = append(inputData.dataResponses[<-urlChan], time)
}
func httpRequest(waitChan chan struct{}, inputData inputDataStruct) {
//url := <- urlChan
defer close(waitChan)
urlChan := make(chan string)
count := inputData.count
j := 0
for i := range inputData.url {
for j < count {
go getResponse(urlChan, inputData)
urlChan <- inputData.url[i]
j++
}
j = 0
}
}
func parseArgument(item string) []string {
return strings.Split(item, ",")
}
func findMinMaxAvg(values []float64) (min float64, max float64, avg float64) {
if len(values) == 0 {
return 0, 0, 0
}
min = values[0]
max = values[0]
var sum float64 = 0
for _, v := range values {
if v < min {
min = v
}
if v > max {
max = v
}
sum = sum + v
}
var count = float64(len(values))
avg = sum / count
return min, max, avg
}
func printMinMaxAvg(dataResponses map[string][]float64) {
for key, _ := range dataResponses {
min, max, avg := findMinMaxAvg(dataResponses[key])
fmt.Printf("url: %s, min: %f, max: %f, avg: %f \n", key, min, max, avg)
}
}
func main() {
//urlArrChan := make(chan []string)
waitChan := make(chan struct{})
//var dataResponses = map[string][]float64{}
//var noResponses = map[string]int{}
url := flag.String("url", "", "url.")
count := flag.Int("count", 1, "count response.")
timeout := flag.Int("timeout", 1, "count response.")
flag.Parse()
var inputData inputDataStruct
inputData.count = *count
inputData.timeOut = *timeout
inputData.dataResponses = map[string][]float64{}
inputData.noResponses = map[string]int{}
//inputData.urlChan = make(chan string)
//inputData.syncChan = make(chan struct{})
inputData.url = parseArgument(*url)
//inputValue := parseArgument(*url)
start := time.Now()
//i := 0
go httpRequest(waitChan, inputData)
//urlArrChan <- inputValue
<-waitChan
//for i := range inputValue {
// //fmt.Print(inputValue[i])
// inputData.url = inputValue[i]
// httpRequest(inputData)
// //urlChan<-inputValue[i]
// i++
//}
elapsed := time.Since(start).Seconds()
//<-inputData.urlChan
//time.Sleep(1 * time.Second)
fmt.Println(inputData.dataResponses)
printMinMaxAvg(inputData.dataResponses)
fmt.Printf("Total time: %f \n", elapsed)
fmt.Println(inputData.noResponses)
fmt.Scanln()
}
Answer the question
In order to leave comments, you need to log in
You need to add sync.WaitGroup inside the httpRequest function. It will look
something like this:
func httpRequest(waitChan chan struct{}, inputData inputDataStruct) {
//url := <- urlChan
defer close(waitChan)
urlChan := make(chan string)
count := inputData.count
j := 0
var wg sync.WaitGroup
for i := range inputData.url {
for j < count {
wg.Add(1)
go func() {
getResponse(urlChan, inputData)
wg.Done()
}
urlChan <- inputData.url[i]
j++
}
j = 0
}
wg.Wait()
}
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question