tsenart / vegeta

HTTP load testing tool and library. It's over 9000!
http://godoc.org/github.com/tsenart/vegeta/lib
MIT License
23.42k stars 1.36k forks source link

Immediately stop vegeta while using go client #663

Closed vishnuchalla closed 11 months ago

vishnuchalla commented 11 months ago

Question

We have this implementation of vegeta in our code using go-client. We want to make 1000 requests with 50 rps and stop the attack immediately as soon as it finishes those 1000 requests. By the time we call attacker.Stop() in our code [reference] it doesn't seem to be immediately stopping the attack and goes way over 1000 requests (i.e almost 3-4 times) before the attack actually stops which is very frustrating.

Example instance:

2023-11-06T17:55:24Z DBG preparing requests for POST operation in index_report number of requests=1000
2023-11-06T17:55:24Z DBG preparing headers endpoint=http://clair-route-clair-namespace.apps.play-area.perfscale.devcluster.openshift.com/indexer/api/v1/index_report
Requests      [total, rate, throughput]         3473, 50.01, 30.38
Duration      [total, attack, wait]             1m45s, 1m9s, 35.106s
Latencies     [min, mean, 50, 90, 95, 99, max]  20.928ms, 35.884s, 35.552s, 58.75s, 59.437s, 59.894s, 59.994s
Bytes In      [total, mean]                     92886566, 26745.34
Bytes Out     [total, mean]                     64398496, 18542.61
Success       [ratio]                           91.45%
Status Codes  [code:count]                      0:297  201:3176  
Error Set:

Detailed logs for vegeta go-client implementation: go_client_vegeta_logs.txt

But if we try to achieve the same functionality through CLI implementation, it works like a charm. Looks like CLI implementation has an immediate way to stop the attack without calling attacker.Stop() by just verifying the count of requests using Pacer which is not exposed through go-client.

Example instance:

2023-11-06T18:45:42Z DBG preparing requests for POST operation in index_report number of requests=1000
2023-11-06T18:45:42Z DBG preparing headers endpoint=http://clair-route-clair-namespace.apps.play-area.perfscale.devcluster.openshift.com/indexer/api/v1/index_report
Requests      [total, rate, throughput]         1002, 50.05, 18.02
Duration      [total, attack, wait]             55.499s, 20.02s, 35.479s
Latencies     [min, mean, 50, 90, 95, 99, max]  11.794µs, 27.203s, 25.814s, 41.342s, 43.018s, 45.522s, 48.759s
Bytes In      [total, mean]                     29592774, 29533.71
Bytes Out     [total, mean]                     20269379, 20228.92
Success       [ratio]                           99.80%
Status Codes  [code:count]                      0:2  201:1000  
Error Set:

Detailed logs for vegeta CLI implementation: cli_version_vegeta_logs.txt

Is there a hacky/suggested way to implement my GO code in such a way that it immediately stops the attack after 1000 requests similar to what is happening in the CLI version as of today?

tsenart commented 11 months ago

The Pacers are public in the Go module so you could use them, wrap them with your own custom logic or even write your own.

But the easiest thing for you to do is to set the duration of your attack to 1s while keeping the attack rate at 1000 per second.

Try that and let me know if it solved your problem.

vishnuchalla commented 11 months ago

No I am looking to send 1000 requests in total with 50 rps and stop immediately once I am done sending 1000 requests. With the above suggestion, I don't think it would be possible. Also I think I have achieved it with this PR.

tsenart commented 11 months ago

If you want to send 1000 request at 50 req/s, then your duration should be 20s (1000/50)

vishnuchalla commented 11 months ago

If you want to send 1000 request at 50 req/s, then your duration should be 20s (1000/50)

Thanks for the suggestion. I did add a dynamic logic to calculate/adjust duration according to my input requests and rps.