package main import ( "fmt" "github.com/gomodule/redigo/redis" "math" "math/rand" "time" ) /** getRateTest calculates closest value for requests per milliseconds from inputted requests per second Then starts goroutines for getRedis at that interval @param rdbPtr connection is a pointer to the redis connection @param rate int requests per second for the test @param keyMaxValue int max value to query the database and expect a return */ func getRateTest(rdbPtr *redis.Conn, rate int, keyMaxValue int, duration time.Duration) { durationChannel := make(chan bool, 1) x := int(math.Abs(100 / float64(rate) * 10000000)) rateLimiter := time.Tick(time.Duration(x)) timesChan := make(chan time.Duration) errorChan := make(chan bool) endChan := make(chan bool) totalErrorChan := make(chan int) totalTimeChan := make(chan []int64) go keepTotal(timesChan, errorChan, endChan, totalTimeChan, totalErrorChan) fmt.Println("Starting Test at", time.Duration(x), "milliseconds per request...") go func() { for i := 0; i < int(duration.Seconds()); i++ { <-time.Tick(time.Second) } durationChannel <- true }() end := false for { if end { break } select { case <-durationChannel: fmt.Println("Closing Test...") end = true case <-rateLimiter: key := rand.Intn(keyMaxValue) go getRedis(rdbPtr, key, timesChan, errorChan) } } endChan <- true totalTimesFloat := <-totalTimeChan totalErrors := <-totalErrorChan errorRate := totalErrors / len(totalTimesFloat) totalTimes := intToFloat(totalTimesFloat) mean, stddev, perc99, perc95 := getResponseTimes(totalTimes) fmt.Println("Rate test concluded...") fmt.Println("Total Requests:", len(totalTimesFloat)) fmt.Println("Error Rate:", errorRate, "ms") fmt.Println("Mean:", mean, "ms") fmt.Println("Standard Deviation:", stddev, "ms") fmt.Println("95 Percentile:", perc95, "ms") fmt.Println("99 Percentile:", perc99, "ms") }