Skip to content

Commit 953d836

Browse files
authored
Merge pull request #84 from kaleido-io/sendrate-control
Adding control for submission rate.
2 parents 74b4ae8 + a980fb8 commit 953d836

File tree

4 files changed

+18
-6
lines changed

4 files changed

+18
-6
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,9 +133,10 @@ There are various options for creating your own customized tests. A full list of
133133
- All values default to `0` which has the effect of not limiting the rate of the test.
134134
- The test will allow at most `startRate` actions to happen per second. Over the period of `rateRampUpTime` seconds the allowed rate will increase linearly until `endRate` actions per seconds are reached. At this point the test will continue at `endRate` actions per second until the test finishes.
135135
- If `startRate` is the only value that is set, the test will run at that rate for the entire test.
136-
- Waiting for mint transactions to be confirmed before doing the next one
136+
- Waiting for events to be confirmed before doing the next submission
137137
- See `noWaitSubmission` (defaults to `false`).
138138
- When set to `true` each worker routine will perform its action (e.g. minting a token) and wait for confirmation of that event before doing its next action.
139+
- `maxSubmissionsPerSecond` can be used to control the maximum number of submissions per second to avoid overloading the system under test.
139140
- Setting the features of a token being tested
140141
- See `supportsData` and `supportsURI` attributes of a test instance.
141142
- `supportsData` defaults to `true` since the sample token contract used by FireFly supports minting tokens with data. When set to `true` the message included in the mint transaction will include the ID of the worker routine and used to correlate received confirmation events.

cmd/run.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,7 @@ func generateRunnerConfigFromInstance(instance *conf.InstanceConfig, perfConfig
217217
runnerConfig.LogLevel = perfConfig.LogLevel
218218
runnerConfig.SkipMintConfirmations = instance.SkipMintConfirmations
219219
runnerConfig.NoWaitSubmission = instance.NoWaitSubmission
220+
runnerConfig.MaxSubmissionsPerSecond = instance.MaxSubmissionsPerSecond
220221
runnerConfig.Length = instance.Length
221222
runnerConfig.Daemon = perfConfig.Daemon
222223
runnerConfig.LogEvents = perfConfig.LogEvents

internal/conf/conf.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ type RunnerConfig struct {
5454
RampLength time.Duration
5555
SkipMintConfirmations bool // deprecated
5656
NoWaitSubmission bool
57+
MaxSubmissionsPerSecond int
5758
SubscriptionCoreOptions *core.SubscriptionCoreOptions
5859
}
5960

@@ -87,6 +88,7 @@ type InstanceConfig struct {
8788
RampLength time.Duration `json:"rampLength,omitempty" yaml:"rampLength,omitempty"`
8889
SkipMintConfirmations bool `json:"skipMintConfirmations" yaml:"skipMintConfirmations"` // deprecated
8990
NoWaitSubmission bool `json:"noWaitSubmission" yaml:"noWaitSubmission"`
91+
MaxSubmissionsPerSecond int `json:"maxSubmissionsPerSecond" yaml:"maxSubmissionsPerSecond"`
9092
DelinquentAction string `json:"delinquentAction,omitempty" yaml:"delinquentAction,omitempty"`
9193
PerWorkerSigningKeyPrefix string `json:"perWorkerSigningKeyPrefix,omitempty" yaml:"perWorkerSigningKeyPrefix,omitempty"`
9294
SubscriptionCoreOptions *core.SubscriptionCoreOptions `json:"subscriptionOptions,omitempty" yaml:"subscriptionOptions,omitempty"`

internal/perf/perf.go

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
"crypto/tls"
2222
"encoding/json"
2323
"fmt"
24+
"math"
2425
"net/url"
2526
"os"
2627
"os/signal"
@@ -49,9 +50,7 @@ const workerPrefix = "worker-"
4950
const preparePrefix = "prep-"
5051

5152
var mutex = &sync.Mutex{}
52-
var limiter *rate.Limiter
5353
var TRANSPORT_TYPE = "websockets"
54-
var wsReadAhead = uint16(50)
5554

5655
var METRICS_NAMESPACE = "ffperf"
5756
var METRICS_SUBSYSTEM = "runner"
@@ -540,10 +539,15 @@ func (pr *perfRunner) Start() (err error) {
540539
i := 0
541540
lastCheckedTime := time.Now()
542541

542+
rateLimiter := rate.NewLimiter(rate.Limit(math.MaxFloat64), math.MaxInt)
543+
544+
if pr.cfg.MaxSubmissionsPerSecond > 0 {
545+
rateLimiter = rate.NewLimiter(rate.Limit(pr.cfg.MaxSubmissionsPerSecond), pr.cfg.MaxSubmissionsPerSecond)
546+
}
547+
log.Infof("Sending rate: %f per second with %d burst", rateLimiter.Limit(), rateLimiter.Burst())
543548
perfLoop:
544549
for pr.daemon || time.Now().Unix() < pr.endTime {
545550
timeout := time.After(60 * time.Second)
546-
547551
// If we've been given a maximum number of actions to perform, check if we're done
548552
if pr.cfg.MaxActions > 0 && int64(getMetricVal(totalActionsCounter)) >= pr.cfg.MaxActions {
549553
break perfLoop
@@ -553,21 +557,25 @@ perfLoop:
553557
case <-signalCh:
554558
break perfLoop
555559
case pr.bfr <- i:
560+
err = rateLimiter.Wait(pr.ctx)
561+
if err != nil {
562+
log.Panic(fmt.Errorf("rate limiter failed"))
563+
break perfLoop
564+
}
556565
i++
557566
if time.Since(lastCheckedTime).Seconds() > pr.cfg.MaxTimePerAction.Seconds() {
558567
if pr.detectDelinquentMsgs() && pr.cfg.DelinquentAction == conf.DelinquentActionExit.String() {
559568
break perfLoop
560569
}
561570
lastCheckedTime = time.Now()
562571
}
563-
break
564572
case <-timeout:
565573
if pr.detectDelinquentMsgs() && pr.cfg.DelinquentAction == conf.DelinquentActionExit.String() {
566574
break perfLoop
567575
}
568576
lastCheckedTime = time.Now()
569-
break
570577
}
578+
571579
}
572580

573581
// If configured, check that the balance of the mint recipient address is correct

0 commit comments

Comments
 (0)