func handle_client(conn net.Conn, cc core.ClientConstructor) { reader := bufio.NewReader(conn) dec := json.NewDecoder(reader) enc := json.NewEncoder(conn) var p core.TestParameters if err := dec.Decode(&p); err != nil { log.Println(err) return } log.Println("Received test parameters from commander.") // log.Printf("Hitting %s at %f reqs/s by %d clients during %v.", p.Addr, p.Rate, p.Clients, p.Duration) globalResult, sync := core.SpawnWorkers(cc, p) sync.WaitReady() // ready.Wait(); conn.Write([]byte("DONE\n")) log.Println("Sent DONE notification to commander.") line, err := reader.ReadString('\n') if err != nil || line != "GO\n" { log.Print("Did not receive GO command:", line, err, "\n") return } log.Println("Received go command from commander, starting loading") sync.Go() // start.Done() sync.WaitDone() //wg.Wait() summary := result.ResultSummary{p.Clients, globalResult.AverageThroughput(), globalResult.N_errors} enc.Encode(summary) result.PrintResult(*globalResult, p.Clients) if p.SaveSamples { result.SaveToFile(globalResult, generateHostDateFileName(p.SampleFile)) } log.Printf("Send result: %v\n", summary) conn.Close() log.Println("Closed connection to master.\n") }
func main() { flag.Parse() if *cpuprofile != "" { f, err := os.Create(*cpuprofile) if err != nil { log.Fatal(err) } pprof.StartCPUProfile(f) defer pprof.StopCPUProfile() } rand.Seed(time.Now().Unix()) // numprocs, numprocsdef := 0, 0 hw_threads := runtime.NumCPU() // if *threads < hw_threads { // hw_threads = *threads // } // numprocsdef = runtime.GOMAXPROCS(hw_threads) // numprocsdef = runtime.GOMAXPROCS(4) numprocs := runtime.GOMAXPROCS(0) if *server { distr.StartServer(clientType) return } log.Printf("====================================================\n") hostname, _ := os.Hostname() log.Printf("Starting go load generator with %d HW threads at %s \n", numprocs, hostname) duration, err := time.ParseDuration(*p_duration) if err != nil { panic(err) } // log.Printf("Hitting %s at %d reqs/s by %d clients during %v.", *p_addr, *p_rate, *threads, duration) parameters := core.TestParameters{Addr: *p_addr, Rate: float64(*p_rate), Duration: duration, Clients: *threads, SaveSamples: (*dataOutput != ""), SampleFile: *dataOutput} var globalResult result.Result if *commander { serverfilecontents, err := ioutil.ReadFile(*serverfile) if err != nil { panic(err) } lines := strings.Split(string(serverfilecontents), "\n") var servers []string for _, line := range lines { if strings.TrimSpace(line) != "" { servers = append(servers, line) } } log.Printf("Using serverfile %s with contents (%d) %v\n", *serverfile, len(servers), servers) globalResult = distr.StartCommander(parameters, servers, clientType) } else { globalResult = core.StartTest(parameters, clientType) result.PrintResult(globalResult, *threads) if parameters.SaveSamples { result.SaveToFile(&globalResult, parameters.SampleFile) } } // if totalResponses > 0 // log.Printf("TOTAL %d responses in %v, Rate: %v, avgLatency: %v\n", totalResponses, duration, float64(totalResponses)/duration.Seconds(), time.Duration(avgLatency)) }
func StartCommander(p core.TestParameters, servers []string, cc core.ClientConstructor) result.Result { // servers := []string{"192.168.7.1:9988","192.168.9.1:9988", "192.168.10.1:9988", "192.168.11.1:9988"}//,"192.168.8.1:9988", // servers = servers[0:4] if p.Clients-4 <= 0 || p.Rate-1000 <= 0 { res := core.StartTest(p, cc) result.PrintResult(res, p.Clients) return res } localParams := p localParams.Clients, localParams.Rate = min(4, p.Clients), math.Min(float64(1000), p.Rate) p.Clients, p.Rate = (p.Clients-localParams.Clients)/len(servers), (p.Rate-localParams.Rate)/float64(len(servers)) log.Printf("Params to send: %v\n", p) //TODO : divide P properlu if #servers > 1 var serverReady, serverStart sync.WaitGroup serverReady.Add(len(servers)) serverStart.Add(1) returnChannel := make(chan result.ResultSummary) for i, address := range servers { time.Sleep(time.Duration(30 * 1000000)) log.Println("spawning", address) if localParams.Clients == 1 && i == len(servers)-1 && i > 0 { p.Clients = p.Clients + 1 } go serverHandler(address, p, &serverReady, &serverStart, returnChannel) } // wg.Add(localParams.Clients) // ready.Add(localParams.Clients) // start.Add(1) log.Printf("localParams %v\n", localParams) globalResult, localSync := core.SpawnWorkers(cc, localParams) localSync.WaitReady() // ready.Wait() serverReady.Wait() serverStart.Done() time.Sleep(time.Duration(100 * 1000)) //Sleep 50 µs ~ 1/2 RTT //start.Done() // wg.Wait() localSync.Go() localSync.WaitDone() rate := globalResult.AverageThroughput() clients := localParams.Clients errors := globalResult.N_errors log.Printf("LOCAL: %f (%d) \n", rate, globalResult.N_latencySamples) for range servers { summary := <-returnChannel rate += summary.AverageThroughput clients += summary.Clients errors += summary.N_errors } // printResult(*globalResult, localParams.Clients) // fmt.Println() fmt.Print(clients, "\t") globalResult.Sort() tails := []float64{0.5, 0.9, 0.99} fmt.Printf("%.1f\t%d", rate, result.Microseconds(globalResult.AverageLatency())) for _, v := range tails { fmt.Printf("\t%d", result.Microseconds(globalResult.Percentile(v))) } fmt.Printf("\t%d\n", errors) return *globalResult }