|
@@ -12,10 +12,11 @@
|
|
|
// See the License for the specific language governing permissions and
|
|
// See the License for the specific language governing permissions and
|
|
|
// limitations under the License.
|
|
// limitations under the License.
|
|
|
|
|
|
|
|
-package main
|
|
|
|
|
|
|
+package command
|
|
|
|
|
|
|
|
import (
|
|
import (
|
|
|
"context"
|
|
"context"
|
|
|
|
|
+ "errors"
|
|
|
"fmt"
|
|
"fmt"
|
|
|
"log"
|
|
"log"
|
|
|
"sync"
|
|
"sync"
|
|
@@ -23,29 +24,48 @@ import (
|
|
|
|
|
|
|
|
"github.com/coreos/etcd/clientv3"
|
|
"github.com/coreos/etcd/clientv3"
|
|
|
"github.com/coreos/etcd/pkg/stringutil"
|
|
"github.com/coreos/etcd/pkg/stringutil"
|
|
|
|
|
+ "github.com/spf13/cobra"
|
|
|
"golang.org/x/time/rate"
|
|
"golang.org/x/time/rate"
|
|
|
)
|
|
)
|
|
|
|
|
|
|
|
-func runWatcher(getClient getClientFunc, limit int) {
|
|
|
|
|
|
|
+// NewWatchCommand returns the cobra command for "watcher runner".
|
|
|
|
|
+func NewWatchCommand() *cobra.Command {
|
|
|
|
|
+ cmd := &cobra.Command{
|
|
|
|
|
+ Use: "watcher",
|
|
|
|
|
+ Short: "Performs watch operation",
|
|
|
|
|
+ Run: runWatcherFunc,
|
|
|
|
|
+ }
|
|
|
|
|
+ cmd.Flags().IntVar(&rounds, "rounds", 100, "number of rounds to run")
|
|
|
|
|
+ cmd.Flags().DurationVar(&runningTime, "running-time", 60, "number of seconds to run")
|
|
|
|
|
+ cmd.Flags().IntVar(&noOfPrefixes, "total-prefixes", 10, "total no of prefixes to use")
|
|
|
|
|
+ cmd.Flags().IntVar(&watchPerPrefix, "watch-per-prefix", 10, "number of watchers per prefix")
|
|
|
|
|
+ cmd.Flags().IntVar(&reqRate, "req-rate", 30, "rate at which put request will be performed")
|
|
|
|
|
+ cmd.Flags().IntVar(&totalKeys, "total-keys", 1000, "total number of keys to watch")
|
|
|
|
|
+ return cmd
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func runWatcherFunc(cmd *cobra.Command, args []string) {
|
|
|
|
|
+ if len(args) > 0 {
|
|
|
|
|
+ ExitWithError(ExitBadArgs, errors.New("watcher does not take any argument"))
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
ctx := context.Background()
|
|
ctx := context.Background()
|
|
|
- for round := 0; round < limit; round++ {
|
|
|
|
|
|
|
+ for round := 0; round < rounds; round++ {
|
|
|
fmt.Println("round", round)
|
|
fmt.Println("round", round)
|
|
|
- performWatchOnPrefixes(ctx, getClient, round)
|
|
|
|
|
|
|
+ performWatchOnPrefixes(ctx, cmd, round)
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-func performWatchOnPrefixes(ctx context.Context, getClient getClientFunc, round int) {
|
|
|
|
|
- runningTime := 60 * time.Second // time for which operation should be performed
|
|
|
|
|
- noOfPrefixes := 36 // total number of prefixes which will be watched upon
|
|
|
|
|
- watchPerPrefix := 10 // number of watchers per prefix
|
|
|
|
|
- reqRate := 30 // put request per second
|
|
|
|
|
- keyPrePrefix := 30 // max number of keyPrePrefixs for put operation
|
|
|
|
|
-
|
|
|
|
|
|
|
+func performWatchOnPrefixes(ctx context.Context, cmd *cobra.Command, round int) {
|
|
|
|
|
+ keyPerPrefix := totalKeys / noOfPrefixes
|
|
|
prefixes := stringutil.UniqueStrings(5, noOfPrefixes)
|
|
prefixes := stringutil.UniqueStrings(5, noOfPrefixes)
|
|
|
- keys := stringutil.RandomStrings(10, keyPrePrefix)
|
|
|
|
|
|
|
+ keys := stringutil.RandomStrings(10, keyPerPrefix)
|
|
|
|
|
|
|
|
roundPrefix := fmt.Sprintf("%16x", round)
|
|
roundPrefix := fmt.Sprintf("%16x", round)
|
|
|
|
|
|
|
|
|
|
+ eps := endpointsFromFlag(cmd)
|
|
|
|
|
+ dialTimeout := dialTimeoutFromCmd(cmd)
|
|
|
|
|
+
|
|
|
var (
|
|
var (
|
|
|
revision int64
|
|
revision int64
|
|
|
wg sync.WaitGroup
|
|
wg sync.WaitGroup
|
|
@@ -53,7 +73,7 @@ func performWatchOnPrefixes(ctx context.Context, getClient getClientFunc, round
|
|
|
err error
|
|
err error
|
|
|
)
|
|
)
|
|
|
|
|
|
|
|
- client := getClient()
|
|
|
|
|
|
|
+ client := newClient(eps, dialTimeout)
|
|
|
defer client.Close()
|
|
defer client.Close()
|
|
|
|
|
|
|
|
gr, err = getKey(ctx, client, "non-existent")
|
|
gr, err = getKey(ctx, client, "non-existent")
|
|
@@ -62,7 +82,7 @@ func performWatchOnPrefixes(ctx context.Context, getClient getClientFunc, round
|
|
|
}
|
|
}
|
|
|
revision = gr.Header.Revision
|
|
revision = gr.Header.Revision
|
|
|
|
|
|
|
|
- ctxt, cancel := context.WithDeadline(ctx, time.Now().Add(runningTime))
|
|
|
|
|
|
|
+ ctxt, cancel := context.WithDeadline(ctx, time.Now().Add(runningTime*time.Second))
|
|
|
defer cancel()
|
|
defer cancel()
|
|
|
|
|
|
|
|
// generate and put keys in cluster
|
|
// generate and put keys in cluster
|
|
@@ -89,7 +109,7 @@ func performWatchOnPrefixes(ctx context.Context, getClient getClientFunc, round
|
|
|
|
|
|
|
|
for _, prefix := range prefixes {
|
|
for _, prefix := range prefixes {
|
|
|
for j := 0; j < watchPerPrefix; j++ {
|
|
for j := 0; j < watchPerPrefix; j++ {
|
|
|
- rc := getClient()
|
|
|
|
|
|
|
+ rc := newClient(eps, dialTimeout)
|
|
|
rcs = append(rcs, rc)
|
|
rcs = append(rcs, rc)
|
|
|
|
|
|
|
|
watchPrefix := roundPrefix + "-" + prefix
|
|
watchPrefix := roundPrefix + "-" + prefix
|