Browse Source

etcd-runner: add rate limiting in doRounds()

fanmin shi 8 years ago
parent
commit
fa85445ef8
1 changed files with 17 additions and 18 deletions
  1. 17 18
      tools/functional-tester/etcd-runner/command/global.go

+ 17 - 18
tools/functional-tester/etcd-runner/command/global.go

@@ -15,6 +15,7 @@
 package command
 package command
 
 
 import (
 import (
+	"context"
 	"fmt"
 	"fmt"
 	"log"
 	"log"
 	"sync"
 	"sync"
@@ -23,25 +24,18 @@ import (
 	"github.com/coreos/etcd/clientv3"
 	"github.com/coreos/etcd/clientv3"
 
 
 	"github.com/spf13/cobra"
 	"github.com/spf13/cobra"
+	"golang.org/x/time/rate"
 )
 )
 
 
+// shared flags
 var (
 var (
-	rounds                 int           // total number of rounds the operation needs to be performed
-	totalClientConnections int           // total number of client connections to be made with server
-	noOfPrefixes           int           // total number of prefixes which will be watched upon
-	watchPerPrefix         int           // number of watchers per prefix
-	reqRate                int           // put request per second
-	totalKeys              int           // total number of keys for operation
-	runningTime            time.Duration // time for which operation should be performed
+	totalClientConnections int // total number of client connections to be made with server
+	endpoints              []string
+	dialTimeout            time.Duration
+	rounds                 int // total number of rounds to run; set to <= 0 to run forever.
+	reqRate                int // maximum number of requests per second.
 )
 )
 
 
-// GlobalFlags are flags that defined globally
-// and are inherited to all sub-commands.
-type GlobalFlags struct {
-	Endpoints   []string
-	DialTimeout time.Duration
-}
-
 type roundClient struct {
 type roundClient struct {
 	c        *clientv3.Client
 	c        *clientv3.Client
 	progress int
 	progress int
@@ -61,16 +55,21 @@ func newClient(eps []string, timeout time.Duration) *clientv3.Client {
 	return c
 	return c
 }
 }
 
 
-func doRounds(rcs []roundClient, rounds int) {
+func doRounds(rcs []roundClient, rounds int, requests int) {
 	var mu sync.Mutex
 	var mu sync.Mutex
 	var wg sync.WaitGroup
 	var wg sync.WaitGroup
 
 
 	wg.Add(len(rcs))
 	wg.Add(len(rcs))
 	finished := make(chan struct{})
 	finished := make(chan struct{})
+	limiter := rate.NewLimiter(rate.Limit(reqRate), reqRate)
 	for i := range rcs {
 	for i := range rcs {
 		go func(rc *roundClient) {
 		go func(rc *roundClient) {
 			defer wg.Done()
 			defer wg.Done()
-			for rc.progress < rounds {
+			for rc.progress < rounds || rounds <= 0 {
+				if err := limiter.WaitN(context.Background(), requests/len(rcs)); err != nil {
+					log.Panicf("rate limiter error %v", err)
+				}
+
 				for rc.acquire() != nil { /* spin */
 				for rc.acquire() != nil { /* spin */
 				}
 				}
 
 
@@ -85,7 +84,7 @@ func doRounds(rcs []roundClient, rounds int) {
 				finished <- struct{}{}
 				finished <- struct{}{}
 
 
 				mu.Lock()
 				mu.Lock()
-				for rc.release() != nil {
+				for rc.release() != nil { /* spin */
 					mu.Unlock()
 					mu.Unlock()
 					mu.Lock()
 					mu.Lock()
 				}
 				}
@@ -95,7 +94,7 @@ func doRounds(rcs []roundClient, rounds int) {
 	}
 	}
 
 
 	start := time.Now()
 	start := time.Now()
-	for i := 1; i < len(rcs)*rounds+1; i++ {
+	for i := 1; i < len(rcs)*rounds+1 || rounds <= 0; i++ {
 		select {
 		select {
 		case <-finished:
 		case <-finished:
 			if i%100 == 0 {
 			if i%100 == 0 {