benchmark-http 0.15.1 → 0.16.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e94467fbbb53392ece96740e56933598ed0a301f8f6a897976e0d6ed59c2b5a0
4
- data.tar.gz: e6ca7937b05e889a91cfca556b715c92724515caaa4bdbecfd523951a16d8739
3
+ metadata.gz: ddd680383fc595b55d77b78490c6acf5acaddf2760e3fcf61fcd852f3fb90c64
4
+ data.tar.gz: 302bf66c3fe10416e6cdffcb56dda7d57e053b864af31521877524f4a32faab3
5
5
  SHA512:
6
- metadata.gz: 172464957224504d73e77fef8139beb33d19d9fe9098b42bf92393617a3f3dcdfee05f7aace4d8909ae05e6b03d9d60405a5e971055367372ab8e989c4aea135
7
- data.tar.gz: ba6cb3332488f08e49d90e707d6333d34b56334e3bd575b4f7d9cb129b4dee75b9bc7a3a318a3be392f01a13594fd6537921bda27800aa53f58a38584da92d67
6
+ metadata.gz: 2f1c0173286d02236604f0e599aded82384936e0dfa0629e8eccfe348b8be6846cafdbc81d062655b91ee605071d471fe7c3b294f0701c8c3935107d464eec92
7
+ data.tar.gz: 65abd131693f16c9ed9c40a5b2c5e461ef33b99cf5f8fcb91d3fb7bb72d5af4723e77835b2a194839b846da35eff9d86bc0e026c3d1a6f7da4a32352449e0440
checksums.yaml.gz.sig ADDED
Binary file
@@ -1,22 +1,7 @@
1
- # Copyright, 2018, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
- #
3
- # Permission is hereby granted, free of charge, to any person obtaining a copy
4
- # of this software and associated documentation files (the "Software"), to deal
5
- # in the Software without restriction, including without limitation the rights
6
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
- # copies of the Software, and to permit persons to whom the Software is
8
- # furnished to do so, subject to the following conditions:
9
- #
10
- # The above copyright notice and this permission notice shall be included in
11
- # all copies or substantial portions of the Software.
12
- #
13
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
- # THE SOFTWARE.
1
+ # frozen_string_literal: true
2
+
3
+ # Released under the MIT License.
4
+ # Copyright, 2018-2022, by Samuel Williams.
20
5
 
21
6
  require_relative '../seconds'
22
7
  require_relative '../statistics'
@@ -46,8 +31,7 @@ module Benchmark
46
31
  end
47
32
 
48
33
  def measure_performance(concurrency, endpoint, request_path)
49
- puts
50
- puts "I am running #{concurrency} asynchronous tasks that will each make sequential requests..."
34
+ Console.logger.info(self, url: endpoint.url) {"I am running #{concurrency} asynchronous tasks that will each make sequential requests..."}
51
35
 
52
36
  statistics = Statistics.new(concurrency)
53
37
  task = Async::Task.current
@@ -64,11 +48,13 @@ module Benchmark
64
48
  end
65
49
  end.each(&:wait)
66
50
 
67
- puts "I made #{statistics.count} requests in #{Seconds[statistics.sequential_duration]}. The per-request latency was #{Seconds[statistics.latency]}. That's #{statistics.per_second.round(2)} asynchronous requests/second."
51
+ Console.logger.info(self, url: endpoint.url, concurrency: concurrency, statistics: statistics) do |buffer|
52
+ buffer.puts "I made #{statistics.count} requests in #{Seconds[statistics.sequential_duration]}. The per-request latency was #{Seconds[statistics.latency]}. That's #{statistics.per_second.round(2)} asynchronous requests/second."
68
53
 
69
- puts "\t Variance: #{Seconds[statistics.variance]}"
70
- puts "\tStandard Deviation: #{Seconds[statistics.standard_deviation]}"
71
- puts "\t Standard Error: #{statistics.standard_error}"
54
+ buffer.puts "\t Variance: #{Seconds[statistics.variance]}"
55
+ buffer.puts "\tStandard Deviation: #{Seconds[statistics.standard_deviation]}"
56
+ buffer.puts "\t Standard Error: #{statistics.standard_error}"
57
+ end
72
58
 
73
59
  return statistics
74
60
  end
@@ -77,9 +63,9 @@ module Benchmark
77
63
  endpoint = Async::HTTP::Endpoint.parse(url)
78
64
  request_path = endpoint.url.request_uri
79
65
 
80
- puts "I am going to benchmark #{url}..."
66
+ Console.logger.info(self) {"I am going to benchmark #{url}..."}
81
67
 
82
- Async::Reactor.run do |task|
68
+ Sync do |task|
83
69
  statistics = []
84
70
  minimum = @options[:minimum]
85
71
 
@@ -110,15 +96,16 @@ module Benchmark
110
96
  end
111
97
  end
112
98
 
113
- puts "Your server can handle #{statistics.last.concurrency} concurrent requests."
114
-
115
- puts "At this level of concurrency, requests have ~#{(statistics.last.latency / statistics.first.latency).round(2)}x higher latency."
99
+ Console.logger.info(self) do |buffer|
100
+ buffer.puts "Your server can handle #{statistics.last.concurrency} concurrent requests."
101
+ buffer.puts "At this level of concurrency, requests have ~#{(statistics.last.latency / statistics.first.latency).round(2)}x higher latency."
102
+ end
116
103
  end
117
104
  end
118
105
 
119
106
  def call
120
107
  @hosts.each do |host|
121
- run(host).wait
108
+ run(host)
122
109
  end
123
110
  end
124
111
  end
@@ -1,22 +1,7 @@
1
- # Copyright, 2020, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
- #
3
- # Permission is hereby granted, free of charge, to any person obtaining a copy
4
- # of this software and associated documentation files (the "Software"), to deal
5
- # in the Software without restriction, including without limitation the rights
6
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
- # copies of the Software, and to permit persons to whom the Software is
8
- # furnished to do so, subject to the following conditions:
9
- #
10
- # The above copyright notice and this permission notice shall be included in
11
- # all copies or substantial portions of the Software.
12
- #
13
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
- # THE SOFTWARE.
1
+ # frozen_string_literal: true
2
+
3
+ # Released under the MIT License.
4
+ # Copyright, 2020-2022, by Samuel Williams.
20
5
 
21
6
  require_relative '../seconds'
22
7
  require_relative '../statistics'
@@ -44,7 +29,7 @@ module Benchmark
44
29
  many :urls, "The urls to hammer."
45
30
 
46
31
  def measure_performance(concurrency, count, endpoint, request_path)
47
- puts "I am running #{concurrency} asynchronous tasks that will each make #{count} sequential requests..."
32
+ Console.logger.info(self) {"I am running #{concurrency} asynchronous tasks that will each make #{count} sequential requests..."}
48
33
 
49
34
  statistics = Statistics.new(concurrency)
50
35
  task = Async::Task.current
@@ -53,7 +38,7 @@ module Benchmark
53
38
  progress_task = task.async do |child|
54
39
  while true
55
40
  child.sleep(1)
56
- statistics.print
41
+ Console.logger.info(self, statistics)
57
42
  end
58
43
  end
59
44
 
@@ -73,12 +58,13 @@ module Benchmark
73
58
 
74
59
  progress_task&.stop
75
60
 
76
- puts "I made #{statistics.count} requests in #{Seconds[statistics.sequential_duration]}. The per-request latency was #{Seconds[statistics.latency]}. That's #{statistics.per_second} asynchronous requests/second."
77
- puts "\t Variance: #{Seconds[statistics.variance]}"
78
- puts "\tStandard Deviation: #{Seconds[statistics.standard_deviation]}"
79
- puts "\t Standard Error: #{Seconds[statistics.standard_error]}"
80
-
81
- statistics.print
61
+ Console.logger.info(self) do |buffer|
62
+ buffer.puts "I made #{statistics.count} requests in #{Seconds[statistics.sequential_duration]}. The per-request latency was #{Seconds[statistics.latency]}. That's #{statistics.per_second} asynchronous requests/second."
63
+ buffer.puts "\t Variance: #{Seconds[statistics.variance]}"
64
+ buffer.puts "\tStandard Deviation: #{Seconds[statistics.standard_deviation]}"
65
+ buffer.puts "\t Standard Error: #{Seconds[statistics.standard_error]}"
66
+ buffer.puts statistics
67
+ end
82
68
 
83
69
  return statistics
84
70
  end
@@ -91,9 +77,9 @@ module Benchmark
91
77
  endpoint = Async::HTTP::Endpoint.parse(url, alpn_protocols: self.alpn_protocols)
92
78
  request_path = endpoint.url.request_uri
93
79
 
94
- puts "I am going to benchmark #{url}..."
80
+ Console.logger.info(self) {"I am going to benchmark #{url}..."}
95
81
 
96
- Async do |task|
82
+ Sync do |task|
97
83
  statistics = []
98
84
 
99
85
  base = measure_performance(@options[:concurrency], @options[:count], endpoint, request_path)
@@ -103,7 +89,7 @@ module Benchmark
103
89
  def call
104
90
  while true
105
91
  @urls.each do |url|
106
- run(url).wait
92
+ run(url)
107
93
  end
108
94
 
109
95
  if @interval
@@ -1,22 +1,7 @@
1
- # Copyright, 2018, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
- #
3
- # Permission is hereby granted, free of charge, to any person obtaining a copy
4
- # of this software and associated documentation files (the "Software"), to deal
5
- # in the Software without restriction, including without limitation the rights
6
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
- # copies of the Software, and to permit persons to whom the Software is
8
- # furnished to do so, subject to the following conditions:
9
- #
10
- # The above copyright notice and this permission notice shall be included in
11
- # all copies or substantial portions of the Software.
12
- #
13
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
- # THE SOFTWARE.
1
+ # frozen_string_literal: true
2
+
3
+ # Released under the MIT License.
4
+ # Copyright, 2019-2022, by Samuel Williams.
20
5
 
21
6
  require_relative '../seconds'
22
7
  require_relative '../statistics'
@@ -45,7 +30,7 @@ module Benchmark
45
30
  end
46
31
 
47
32
  def measure_performance(concurrency, endpoint, request_path)
48
- puts "I am running #{concurrency} asynchronous tasks that will each make sequential requests..."
33
+ Console.logger.info(self) {"I am running #{concurrency} asynchronous tasks that will each make sequential requests..."}
49
34
 
50
35
  statistics = Statistics.new(concurrency)
51
36
  task = Async::Task.current
@@ -62,10 +47,12 @@ module Benchmark
62
47
  end
63
48
  end.each(&:wait)
64
49
 
65
- puts "I made #{statistics.count} requests in #{Seconds[statistics.sequential_duration]}. The per-request latency was #{Seconds[statistics.latency]}. That's #{statistics.per_second} asynchronous requests/second."
66
- puts "\t Variance: #{Seconds[statistics.variance]}"
67
- puts "\tStandard Deviation: #{Seconds[statistics.standard_deviation]}"
68
- puts "\t Standard Error: #{Seconds[statistics.standard_error]}"
50
+ Console.logger.info(self, statistics: statistics) do |buffer|
51
+ buffer.puts "I made #{statistics.count} requests in #{Seconds[statistics.sequential_duration]}. The per-request latency was #{Seconds[statistics.latency]}. That's #{statistics.per_second} asynchronous requests/second."
52
+ buffer.puts "\t Variance: #{Seconds[statistics.variance]}"
53
+ buffer.puts "\tStandard Deviation: #{Seconds[statistics.standard_deviation]}"
54
+ buffer.puts "\t Standard Error: #{Seconds[statistics.standard_error]}"
55
+ end
69
56
 
70
57
  return statistics
71
58
  end
@@ -74,9 +61,9 @@ module Benchmark
74
61
  endpoint = Async::HTTP::Endpoint.parse(url)
75
62
  request_path = endpoint.url.request_uri
76
63
 
77
- puts "I am going to benchmark #{url}..."
64
+ Console.logger.info(self) {"I am going to benchmark #{url}..."}
78
65
 
79
- Async::Reactor.run do |task|
66
+ Sync do |task|
80
67
  statistics = []
81
68
 
82
69
  base = measure_performance(@options[:concurrency], endpoint, request_path)
@@ -85,7 +72,7 @@ module Benchmark
85
72
 
86
73
  def call
87
74
  @hosts.each do |host|
88
- run(host).wait
75
+ run(host)
89
76
  end
90
77
  end
91
78
  end
@@ -1,22 +1,7 @@
1
- # Copyright, 2018, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
- #
3
- # Permission is hereby granted, free of charge, to any person obtaining a copy
4
- # of this software and associated documentation files (the "Software"), to deal
5
- # in the Software without restriction, including without limitation the rights
6
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
- # copies of the Software, and to permit persons to whom the Software is
8
- # furnished to do so, subject to the following conditions:
9
- #
10
- # The above copyright notice and this permission notice shall be included in
11
- # all copies or substantial portions of the Software.
12
- #
13
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
- # THE SOFTWARE.
1
+ # frozen_string_literal: true
2
+
3
+ # Released under the MIT License.
4
+ # Copyright, 2018-2022, by Samuel Williams.
20
5
 
21
6
  require_relative '../spider'
22
7
 
@@ -42,7 +27,7 @@ module Benchmark
42
27
  many :urls, "One or more hosts to benchmark"
43
28
 
44
29
  def log(method, url, response)
45
- Console.logger.call(self, severity: (response.failure? ? :warn : :info)) do |buffer|
30
+ Console.logger.public_send(response.failure? ? :warn : :info, self) do |buffer|
46
31
  buffer.puts "#{method} #{url} -> #{response.version} #{response.status} (#{response.body&.length || 'unspecified'} bytes)"
47
32
 
48
33
  response.headers.each do |key, value|
@@ -56,7 +41,7 @@ module Benchmark
56
41
 
57
42
  statistics = spider.call(@urls, &self.method(:log))
58
43
 
59
- statistics.print
44
+ Console.logger.info(self, statistics: statistics)
60
45
 
61
46
  return statistics
62
47
  end
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Released under the MIT License.
4
+ # Copyright, 2022, by Samuel Williams.
5
+
6
+ require_relative '../seconds'
7
+ require_relative '../statistics'
8
+
9
+ require 'async'
10
+ require 'async/barrier'
11
+ require 'async/http/client'
12
+ require 'async/http/endpoint'
13
+
14
+ require 'samovar'
15
+
16
+ module Benchmark
17
+ module HTTP
18
+ module Command
19
+ class Wait < Samovar::Command
20
+ self.description = "Measure how long it takes for an endpoint to become accessible."
21
+
22
+ options do
23
+ option '-w/--wait <time>', "The maximum wait time.", default: 10, type: Float
24
+ end
25
+
26
+ many :hosts, "The hosts to wait for."
27
+
28
+ def run(url, parent: Async::Task.current)
29
+ endpoint = Async::HTTP::Endpoint.parse(url)
30
+ request_path = endpoint.url.request_uri
31
+ maximum_wait = @options[:wait]
32
+
33
+ parent.async do
34
+ clock = Async::Clock.start
35
+
36
+ client = Async::HTTP::Client.new(endpoint)
37
+
38
+ begin
39
+ client.get(request_path).tap(&:finish)
40
+ rescue => error
41
+ if clock.total > maximum_wait
42
+ raise
43
+ else
44
+ sleep 0.01
45
+ retry
46
+ end
47
+ end
48
+
49
+ Console.logger.info(self) {"#{url} is ready after #{clock.total} seconds."}
50
+ ensure
51
+ client.close
52
+ end
53
+ end
54
+
55
+ def call
56
+ Sync do |task|
57
+ barrier = Async::Barrier.new
58
+
59
+ @hosts.each do |host|
60
+ run(host, parent: barrier)
61
+ end
62
+
63
+ barrier.wait
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
@@ -1,27 +1,13 @@
1
- # Copyright, 2018, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
- #
3
- # Permission is hereby granted, free of charge, to any person obtaining a copy
4
- # of this software and associated documentation files (the "Software"), to deal
5
- # in the Software without restriction, including without limitation the rights
6
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
- # copies of the Software, and to permit persons to whom the Software is
8
- # furnished to do so, subject to the following conditions:
9
- #
10
- # The above copyright notice and this permission notice shall be included in
11
- # all copies or substantial portions of the Software.
12
- #
13
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
- # THE SOFTWARE.
1
+ # frozen_string_literal: true
2
+
3
+ # Released under the MIT License.
4
+ # Copyright, 2018-2022, by Samuel Williams.
20
5
 
21
6
  require_relative 'command/latency'
22
7
  require_relative 'command/concurrency'
23
8
  require_relative 'command/spider'
24
9
  require_relative 'command/hammer'
10
+ require_relative 'command/wait'
25
11
 
26
12
  require_relative 'version'
27
13
  require 'samovar'
@@ -48,6 +34,7 @@ module Benchmark
48
34
  'concurrency' => Concurrency,
49
35
  'spider' => Spider,
50
36
  'hammer' => Hammer,
37
+ 'wait' => Wait,
51
38
  }
52
39
 
53
40
  def verbose?
@@ -63,8 +50,6 @@ module Benchmark
63
50
  Console.logger.debug!
64
51
  elsif quiet?
65
52
  Console.logger.warn!
66
- else
67
- Console.logger.info!
68
53
  end
69
54
 
70
55
  if @options[:version]
@@ -1,22 +1,7 @@
1
- # Copyright, 2018, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
- #
3
- # Permission is hereby granted, free of charge, to any person obtaining a copy
4
- # of this software and associated documentation files (the "Software"), to deal
5
- # in the Software without restriction, including without limitation the rights
6
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
- # copies of the Software, and to permit persons to whom the Software is
8
- # furnished to do so, subject to the following conditions:
9
- #
10
- # The above copyright notice and this permission notice shall be included in
11
- # all copies or substantial portions of the Software.
12
- #
13
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
- # THE SOFTWARE.
1
+ # frozen_string_literal: true
2
+
3
+ # Released under the MIT License.
4
+ # Copyright, 2018-2022, by Samuel Williams.
20
5
 
21
6
  require 'trenni/sanitize'
22
7
 
@@ -1,22 +1,7 @@
1
- # Copyright, 2018, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
- #
3
- # Permission is hereby granted, free of charge, to any person obtaining a copy
4
- # of this software and associated documentation files (the "Software"), to deal
5
- # in the Software without restriction, including without limitation the rights
6
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
- # copies of the Software, and to permit persons to whom the Software is
8
- # furnished to do so, subject to the following conditions:
9
- #
10
- # The above copyright notice and this permission notice shall be included in
11
- # all copies or substantial portions of the Software.
12
- #
13
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
- # THE SOFTWARE.
1
+ # frozen_string_literal: true
2
+
3
+ # Released under the MIT License.
4
+ # Copyright, 2018-2022, by Samuel Williams.
20
5
 
21
6
  module Benchmark
22
7
  module HTTP
@@ -1,22 +1,7 @@
1
- # Copyright, 2018, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
- #
3
- # Permission is hereby granted, free of charge, to any person obtaining a copy
4
- # of this software and associated documentation files (the "Software"), to deal
5
- # in the Software without restriction, including without limitation the rights
6
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
- # copies of the Software, and to permit persons to whom the Software is
8
- # furnished to do so, subject to the following conditions:
9
- #
10
- # The above copyright notice and this permission notice shall be included in
11
- # all copies or substantial portions of the Software.
12
- #
13
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
- # THE SOFTWARE.
1
+ # frozen_string_literal: true
2
+
3
+ # Released under the MIT License.
4
+ # Copyright, 2020-2022, by Samuel Williams.
20
5
 
21
6
  require_relative 'seconds'
22
7
  require_relative 'statistics'
@@ -117,10 +102,10 @@ module Benchmark
117
102
  extract_links(url, response) do |href|
118
103
  fetch(statistics, client, href, depth&.-(1), fetched, &block)
119
104
  end.each(&:wait)
120
- rescue Async::TimeoutError
121
- Console.logger.error(self) {"Timeout while fetching #{url}"}
122
- rescue StandardError
123
- Console.logger.error(self) {$!}
105
+ rescue Async::TimeoutError => error
106
+ Console.logger.error(self, error, url: url)
107
+ rescue StandardError => error
108
+ Console.logger.error(self, error)
124
109
  end
125
110
 
126
111
  sync def call(urls, &block)
@@ -1,22 +1,7 @@
1
- # Copyright, 2018, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
- #
3
- # Permission is hereby granted, free of charge, to any person obtaining a copy
4
- # of this software and associated documentation files (the "Software"), to deal
5
- # in the Software without restriction, including without limitation the rights
6
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
- # copies of the Software, and to permit persons to whom the Software is
8
- # furnished to do so, subject to the following conditions:
9
- #
10
- # The above copyright notice and this permission notice shall be included in
11
- # all copies or substantial portions of the Software.
12
- #
13
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
- # THE SOFTWARE.
1
+ # frozen_string_literal: true
2
+
3
+ # Released under the MIT License.
4
+ # Copyright, 2018-2022, by Samuel Williams.
20
5
 
21
6
  require 'async/clock'
22
7
 
@@ -133,14 +118,27 @@ module Benchmark
133
118
  end until confident?(confidence_factor)
134
119
  end
135
120
 
136
- def print(out = STDOUT)
121
+ def to_s
137
122
  if self.valid?
138
- out.puts "#{@samples.size} samples. #{per_second} requests per second. S/D: #{Seconds[standard_deviation]}."
123
+ "#{@samples.size} samples. #{per_second} requests per second. S/D: #{Seconds[standard_deviation]}."
139
124
  else
140
- out.puts "Not enough samples."
125
+ "Not enough samples."
141
126
  end
142
127
  end
143
128
 
129
+ def to_json(options)
130
+ {
131
+ count: self.count,
132
+ concurrency: self.concurrency,
133
+ latency: self.latency,
134
+ standard_deviation: self.standard_deviation,
135
+ standard_error: self.standard_error,
136
+ per_second: self.per_second,
137
+ duration: self.duration,
138
+ variance: self.variance,
139
+ }.to_json(options)
140
+ end
141
+
144
142
  private
145
143
 
146
144
  def confident?(factor)
@@ -1,25 +1,10 @@
1
- # Copyright, 2018, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
- #
3
- # Permission is hereby granted, free of charge, to any person obtaining a copy
4
- # of this software and associated documentation files (the "Software"), to deal
5
- # in the Software without restriction, including without limitation the rights
6
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
- # copies of the Software, and to permit persons to whom the Software is
8
- # furnished to do so, subject to the following conditions:
9
- #
10
- # The above copyright notice and this permission notice shall be included in
11
- # all copies or substantial portions of the Software.
12
- #
13
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
- # THE SOFTWARE.
1
+ # frozen_string_literal: true
2
+
3
+ # Released under the MIT License.
4
+ # Copyright, 2018-2022, by Samuel Williams.
20
5
 
21
6
  module Benchmark
22
7
  module HTTP
23
- VERSION = "0.15.1"
8
+ VERSION = "0.16.0"
24
9
  end
25
10
  end
@@ -1,22 +1,7 @@
1
- # Copyright, 2018, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
- #
3
- # Permission is hereby granted, free of charge, to any person obtaining a copy
4
- # of this software and associated documentation files (the "Software"), to deal
5
- # in the Software without restriction, including without limitation the rights
6
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
- # copies of the Software, and to permit persons to whom the Software is
8
- # furnished to do so, subject to the following conditions:
9
- #
10
- # The above copyright notice and this permission notice shall be included in
11
- # all copies or substantial portions of the Software.
12
- #
13
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
- # THE SOFTWARE.
1
+ # frozen_string_literal: true
2
+
3
+ # Released under the MIT License.
4
+ # Copyright, 2018-2022, by Samuel Williams.
20
5
 
21
6
  require_relative "http/version"
22
7
  require_relative "http/command"
data/license.md ADDED
@@ -0,0 +1,21 @@
1
+ # MIT License
2
+
3
+ Copyright, 2018-2022, by Samuel Williams.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/readme.md ADDED
@@ -0,0 +1,195 @@
1
+ # Benchmark::HTTP
2
+
3
+ An asynchronous HTTP benchmark tool built on top of [async](https://github.com/socketry/async), [async-io](https://github.com/socketry/async-io) and [async-http](https://github.com/socketry/async-http). Useful for analysing server performance. Supports HTTP1 and HTTP2.
4
+
5
+ [![Development Status](https://github.com/socketry/benchmark-http/workflows/Test/badge.svg)](https://github.com/socketry/benchmark-http/actions?workflow=Test)
6
+
7
+ ## Installation
8
+
9
+ Install it yourself:
10
+
11
+ $ gem install benchmark-http
12
+
13
+ ## Usage
14
+
15
+ You can run `benchmark-http` is a top level tool for invoking specific benchmarks.
16
+
17
+ ### Spider
18
+
19
+ This benchmark spiders a website and generates some statistics on general access time.
20
+
21
+ ``` shell
22
+ $ benchmark-http spider https://www.oriontransfer.co.nz/welcome/index
23
+ HEAD https://www.oriontransfer.co.nz/welcome/index -> HTTP/2.0 404 (unspecified bytes)
24
+ GET https://www.oriontransfer.co.nz/welcome/index (depth = 10)
25
+ GET https://www.oriontransfer.co.nz/welcome/index -> HTTP/2.0 404 (2263 bytes)
26
+ HEAD https://www.oriontransfer.co.nz/products/index -> HTTP/2.0 200 (unspecified bytes)
27
+ GET https://www.oriontransfer.co.nz/products/index (depth = 9)
28
+ HEAD https://www.oriontransfer.co.nz/services/index -> HTTP/2.0 200 (unspecified bytes)
29
+ GET https://www.oriontransfer.co.nz/services/index (depth = 9)
30
+ HEAD https://www.oriontransfer.co.nz/support/index -> HTTP/2.0 200 (unspecified bytes)
31
+ GET https://www.oriontransfer.co.nz/support/index (depth = 9)
32
+ HEAD https://www.oriontransfer.co.nz/support/contact-us -> HTTP/2.0 307 (unspecified bytes)
33
+ Following redirect to https://www.oriontransfer.co.nz/support/contact-us/index...
34
+ HEAD https://www.oriontransfer.co.nz/support/terms-of-service -> HTTP/2.0 200 (unspecified bytes)
35
+ GET https://www.oriontransfer.co.nz/support/terms-of-service (depth = 9)
36
+ GET https://www.oriontransfer.co.nz/products/index -> HTTP/2.0 200 (3469 bytes)
37
+ GET https://www.oriontransfer.co.nz/services/index -> HTTP/2.0 200 (2488 bytes)
38
+ GET https://www.oriontransfer.co.nz/support/index -> HTTP/2.0 200 (2246 bytes)
39
+ HEAD https://www.oriontransfer.co.nz/support/contact-us/index -> HTTP/2.0 200 (unspecified bytes)
40
+ GET https://www.oriontransfer.co.nz/support/contact-us/index (depth = 8)
41
+ GET https://www.oriontransfer.co.nz/support/terms-of-service -> HTTP/2.0 200 (8466 bytes)
42
+ HEAD https://www.oriontransfer.co.nz/products/library-inspector/index -> HTTP/2.0 200 (unspecified bytes)
43
+ GET https://www.oriontransfer.co.nz/products/library-inspector/index (depth = 8)
44
+ HEAD https://www.oriontransfer.co.nz/products/truth-tables/index -> HTTP/2.0 200 (unspecified bytes)
45
+ GET https://www.oriontransfer.co.nz/products/truth-tables/index (depth = 8)
46
+ HEAD https://www.oriontransfer.co.nz/products/fingerprint/index -> HTTP/2.0 200 (unspecified bytes)
47
+ GET https://www.oriontransfer.co.nz/products/fingerprint/index (depth = 8)
48
+ HEAD https://www.oriontransfer.co.nz/services/internet-services -> HTTP/2.0 200 (unspecified bytes)
49
+ GET https://www.oriontransfer.co.nz/services/internet-services (depth = 8)
50
+ HEAD https://www.oriontransfer.co.nz/services/software-development -> HTTP/2.0 200 (unspecified bytes)
51
+ GET https://www.oriontransfer.co.nz/services/software-development (depth = 8)
52
+ HEAD https://www.oriontransfer.co.nz/services/systems-administration -> HTTP/2.0 200 (unspecified bytes)
53
+ GET https://www.oriontransfer.co.nz/services/systems-administration (depth = 8)
54
+ HEAD https://www.oriontransfer.co.nz/services/website-development -> HTTP/2.0 200 (unspecified bytes)
55
+ GET https://www.oriontransfer.co.nz/services/website-development (depth = 8)
56
+ HEAD https://www.oriontransfer.co.nz/support/contact-us/ -> HTTP/2.0 307 (unspecified bytes)
57
+ Following redirect to https://www.oriontransfer.co.nz/support/contact-us/index...
58
+ GET https://www.oriontransfer.co.nz/support/contact-us/index -> HTTP/2.0 200 (3094 bytes)
59
+ GET https://www.oriontransfer.co.nz/products/library-inspector/index -> HTTP/2.0 200 (5592 bytes)
60
+ GET https://www.oriontransfer.co.nz/products/truth-tables/index -> HTTP/2.0 200 (4160 bytes)
61
+ GET https://www.oriontransfer.co.nz/products/fingerprint/index -> HTTP/2.0 200 (4414 bytes)
62
+ GET https://www.oriontransfer.co.nz/services/internet-services -> HTTP/2.0 200 (3362 bytes)
63
+ GET https://www.oriontransfer.co.nz/services/software-development -> HTTP/2.0 200 (3521 bytes)
64
+ GET https://www.oriontransfer.co.nz/services/systems-administration -> HTTP/2.0 200 (2979 bytes)
65
+ GET https://www.oriontransfer.co.nz/services/website-development -> HTTP/2.0 200 (3943 bytes)
66
+ HEAD https://www.oriontransfer.co.nz/_gallery/products/library-inspector/_screenshots/large/Library%20Inspector%20(Libraries).png -> HTTP/2.0 200 (unspecified bytes)
67
+ Unsupported content type: image/png
68
+ HEAD https://www.oriontransfer.co.nz/_gallery/products/library-inspector/_screenshots/large/Library%20Inspector%20(Libraries%20Disassembly).png -> HTTP/2.0 200 (unspecified bytes)
69
+ Unsupported content type: image/png
70
+ HEAD https://www.oriontransfer.co.nz/_gallery/products/library-inspector/_screenshots/large/Library%20Inspector%20(Libraries%20QuickLook).png -> HTTP/2.0 200 (unspecified bytes)
71
+ Unsupported content type: image/png
72
+ HEAD https://www.oriontransfer.co.nz/_gallery/products/library-inspector/_screenshots/large/Library%20Inspector%20(App).png -> HTTP/2.0 200 (unspecified bytes)
73
+ Unsupported content type: image/png
74
+ HEAD https://www.oriontransfer.co.nz/_gallery/products/library-inspector/_screenshots/large/Library%20Inspector%20(App%20Headers).png -> HTTP/2.0 200 (unspecified bytes)
75
+ Unsupported content type: image/png
76
+ HEAD https://www.oriontransfer.co.nz/_gallery/products/truth-tables/_screenshots/large/Reformat%20Expression.png -> HTTP/2.0 200 (unspecified bytes)
77
+ Unsupported content type: image/png
78
+ HEAD https://www.oriontransfer.co.nz/_gallery/products/truth-tables/_screenshots/large/Large%20Tables.png -> HTTP/2.0 200 (unspecified bytes)
79
+ Unsupported content type: image/png
80
+ HEAD https://www.oriontransfer.co.nz/_gallery/products/truth-tables/_screenshots/large/Tutor.png -> HTTP/2.0 200 (unspecified bytes)
81
+ Unsupported content type: image/png
82
+ HEAD https://www.oriontransfer.co.nz/_gallery/products/truth-tables/_screenshots/large/Informative%20Text.png -> HTTP/2.0 200 (unspecified bytes)
83
+ Unsupported content type: image/png
84
+ HEAD https://www.oriontransfer.co.nz/_gallery/products/fingerprint/_screenshots/large/Fingerprint%20(3).png -> HTTP/2.0 200 (unspecified bytes)
85
+ Unsupported content type: image/png
86
+ HEAD https://www.oriontransfer.co.nz/_gallery/products/fingerprint/_screenshots/large/Fingerprint%20(2).png -> HTTP/2.0 200 (unspecified bytes)
87
+ Unsupported content type: image/png
88
+ HEAD https://www.oriontransfer.co.nz/_gallery/products/fingerprint/_screenshots/large/Fingerprint%20(1).png -> HTTP/2.0 200 (unspecified bytes)
89
+ Unsupported content type: image/png
90
+ HEAD https://www.oriontransfer.co.nz/services/training -> HTTP/2.0 200 (unspecified bytes)
91
+ GET https://www.oriontransfer.co.nz/services/training (depth = 7)
92
+ GET https://www.oriontransfer.co.nz/services/training -> HTTP/2.0 200 (2994 bytes)
93
+ 14 samples: 13x 200; 1x 404. 15.12 requests per second. S/D: 35.69ms.
94
+ ```
95
+
96
+ ### Concurrency
97
+
98
+ This benchmark determines the optimal level of concurrency (maximise throughput while keeping latency to a minimum).
99
+
100
+ ``` shell
101
+ $ benchmark-http concurrency https://www.oriontransfer.co.nz/welcome/index
102
+ I am going to benchmark https://www.oriontransfer.co.nz/welcome/index...
103
+ I am running 1 asynchronous tasks that will each make sequential requests...
104
+ I made 273 requests in 52.4s. The per-request latency was 191.79ms. That's 5.214149911737622 asynchronous requests/second.
105
+ Variance: 997.437µs
106
+ Standard Deviation: 31.58ms
107
+ Standard Error: 0.0019114428646174592
108
+ I am running 2 asynchronous tasks that will each make sequential requests...
109
+ I made 177 requests in 16.8s. The per-request latency was 190.19ms. That's 10.51600772540387 asynchronous requests/second.
110
+ Variance: 632.076µs
111
+ Standard Deviation: 25.14ms
112
+ Standard Error: 0.001889722381767832
113
+ I am running 4 asynchronous tasks that will each make sequential requests...
114
+ I made 8 requests in 372.49ms. The per-request latency was 186.25ms. That's 21.476841588829895 asynchronous requests/second.
115
+ Variance: 0.048µs
116
+ Standard Deviation: 219.819µs
117
+ Standard Error: 7.771792696588776e-05
118
+ I am running 8 asynchronous tasks that will each make sequential requests...
119
+ I made 128 requests in 3.0s. The per-request latency was 188.10ms. That's 42.53004421587869 asynchronous requests/second.
120
+ Variance: 399.781µs
121
+ Standard Deviation: 19.99ms
122
+ Standard Error: 0.0017672840585127617
123
+ I am running 16 asynchronous tasks that will each make sequential requests...
124
+ I made 184 requests in 2.2s. The per-request latency was 188.46ms. That's 84.89938672881854 asynchronous requests/second.
125
+ Variance: 548.641µs
126
+ Standard Deviation: 23.42ms
127
+ Standard Error: 0.0017267724185582615
128
+ I am running 32 asynchronous tasks that will each make sequential requests...
129
+ I made 152 requests in 891.06ms. The per-request latency was 187.59ms. That's 170.58399627520865 asynchronous requests/second.
130
+ Variance: 335.694µs
131
+ Standard Deviation: 18.32ms
132
+ Standard Error: 0.00148610620533633
133
+ I am running 64 asynchronous tasks that will each make sequential requests...
134
+ I made 438 requests in 1.3s. The per-request latency was 191.68ms. That's 333.89790173541496 asynchronous requests/second.
135
+ Variance: 1.19ms
136
+ Standard Deviation: 34.51ms
137
+ Standard Error: 0.001648801656177374
138
+ I am running 128 asynchronous tasks that will each make sequential requests...
139
+ I made 360 requests in 533.83ms. The per-request latency was 189.81ms. That's 674.373540567776 asynchronous requests/second.
140
+ Variance: 555.212µs
141
+ Standard Deviation: 23.56ms
142
+ Standard Error: 0.0012418759009531876
143
+ I am running 256 asynchronous tasks that will each make sequential requests...
144
+ I made 512 requests in 463.03ms. The per-request latency was 231.51ms. That's 1105.762787139087 asynchronous requests/second.
145
+ Variance: 888.185µs
146
+ Standard Deviation: 29.80ms
147
+ Standard Error: 0.0013170938569343825
148
+ I am running 192 asynchronous tasks that will each make sequential requests...
149
+ I made 384 requests in 380.97ms. The per-request latency was 190.48ms. That's 1007.9615261872923 asynchronous requests/second.
150
+ Variance: 142.770µs
151
+ Standard Deviation: 11.95ms
152
+ Standard Error: 0.0006097518459132856
153
+ I am running 224 asynchronous tasks that will each make sequential requests...
154
+ I made 448 requests in 411.79ms. The per-request latency was 205.89ms. That's 1087.9398101463066 asynchronous requests/second.
155
+ Variance: 215.480µs
156
+ Standard Deviation: 14.68ms
157
+ Standard Error: 0.0006935294886115942
158
+ I am running 240 asynchronous tasks that will each make sequential requests...
159
+ I made 480 requests in 401.62ms. The per-request latency was 200.81ms. That's 1195.1473779597363 asynchronous requests/second.
160
+ Variance: 292.021µs
161
+ Standard Deviation: 17.09ms
162
+ Standard Error: 0.0007799848849992035
163
+ I am running 248 asynchronous tasks that will each make sequential requests...
164
+ I made 496 requests in 432.58ms. The per-request latency was 216.29ms. That's 1146.621534849607 asynchronous requests/second.
165
+ Variance: 446.681µs
166
+ Standard Deviation: 21.13ms
167
+ Standard Error: 0.0009489813840514241
168
+ I am running 252 asynchronous tasks that will each make sequential requests...
169
+ I made 504 requests in 417.86ms. The per-request latency was 208.93ms. That's 1206.1477638702509 asynchronous requests/second.
170
+ Variance: 222.939µs
171
+ Standard Deviation: 14.93ms
172
+ Standard Error: 0.0006650854376052381
173
+ I am running 254 asynchronous tasks that will each make sequential requests...
174
+ I made 508 requests in 419.67ms. The per-request latency was 209.83ms. That's 1210.4835614086478 asynchronous requests/second.
175
+ Variance: 177.005µs
176
+ Standard Deviation: 13.30ms
177
+ Standard Error: 0.0005902836562252991
178
+ I am running 255 asynchronous tasks that will each make sequential requests...
179
+ I made 510 requests in 434.38ms. The per-request latency was 217.19ms. That's 1174.0936493567908 asynchronous requests/second.
180
+ Variance: 457.592µs
181
+ Standard Deviation: 21.39ms
182
+ Standard Error: 0.000947227304291054
183
+ Your server can handle 255 concurrent requests.
184
+ At this level of concurrency, requests have ~1.13x higher latency.
185
+ ```
186
+
187
+ ## Contributing
188
+
189
+ We welcome contributions to this project.
190
+
191
+ 1. Fork it.
192
+ 2. Create your feature branch (`git checkout -b my-new-feature`).
193
+ 3. Commit your changes (`git commit -am 'Add some feature'`).
194
+ 4. Push to the branch (`git push origin my-new-feature`).
195
+ 5. Create new Pull Request.
data.tar.gz.sig ADDED
Binary file
metadata CHANGED
@@ -1,14 +1,44 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: benchmark-http
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.15.1
4
+ version: 0.16.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel Williams
8
+ - Olle Jonsson
8
9
  autorequire:
9
10
  bindir: bin
10
- cert_chain: []
11
- date: 2021-12-24 00:00:00.000000000 Z
11
+ cert_chain:
12
+ - |
13
+ -----BEGIN CERTIFICATE-----
14
+ MIIE2DCCA0CgAwIBAgIBATANBgkqhkiG9w0BAQsFADBhMRgwFgYDVQQDDA9zYW11
15
+ ZWwud2lsbGlhbXMxHTAbBgoJkiaJk/IsZAEZFg1vcmlvbnRyYW5zZmVyMRIwEAYK
16
+ CZImiZPyLGQBGRYCY28xEjAQBgoJkiaJk/IsZAEZFgJuejAeFw0yMjA4MDYwNDUz
17
+ MjRaFw0zMjA4MDMwNDUzMjRaMGExGDAWBgNVBAMMD3NhbXVlbC53aWxsaWFtczEd
18
+ MBsGCgmSJomT8ixkARkWDW9yaW9udHJhbnNmZXIxEjAQBgoJkiaJk/IsZAEZFgJj
19
+ bzESMBAGCgmSJomT8ixkARkWAm56MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIB
20
+ igKCAYEAomvSopQXQ24+9DBB6I6jxRI2auu3VVb4nOjmmHq7XWM4u3HL+pni63X2
21
+ 9qZdoq9xt7H+RPbwL28LDpDNflYQXoOhoVhQ37Pjn9YDjl8/4/9xa9+NUpl9XDIW
22
+ sGkaOY0eqsQm1pEWkHJr3zn/fxoKPZPfaJOglovdxf7dgsHz67Xgd/ka+Wo1YqoE
23
+ e5AUKRwUuvaUaumAKgPH+4E4oiLXI4T1Ff5Q7xxv6yXvHuYtlMHhYfgNn8iiW8WN
24
+ XibYXPNP7NtieSQqwR/xM6IRSoyXKuS+ZNGDPUUGk8RoiV/xvVN4LrVm9upSc0ss
25
+ RZ6qwOQmXCo/lLcDUxJAgG95cPw//sI00tZan75VgsGzSWAOdjQpFM0l4dxvKwHn
26
+ tUeT3ZsAgt0JnGqNm2Bkz81kG4A2hSyFZTFA8vZGhp+hz+8Q573tAR89y9YJBdYM
27
+ zp0FM4zwMNEUwgfRzv1tEVVUEXmoFCyhzonUUw4nE4CFu/sE3ffhjKcXcY//qiSW
28
+ xm4erY3XAgMBAAGjgZowgZcwCQYDVR0TBAIwADALBgNVHQ8EBAMCBLAwHQYDVR0O
29
+ BBYEFO9t7XWuFf2SKLmuijgqR4sGDlRsMC4GA1UdEQQnMCWBI3NhbXVlbC53aWxs
30
+ aWFtc0BvcmlvbnRyYW5zZmVyLmNvLm56MC4GA1UdEgQnMCWBI3NhbXVlbC53aWxs
31
+ aWFtc0BvcmlvbnRyYW5zZmVyLmNvLm56MA0GCSqGSIb3DQEBCwUAA4IBgQB5sxkE
32
+ cBsSYwK6fYpM+hA5B5yZY2+L0Z+27jF1pWGgbhPH8/FjjBLVn+VFok3CDpRqwXCl
33
+ xCO40JEkKdznNy2avOMra6PFiQyOE74kCtv7P+Fdc+FhgqI5lMon6tt9rNeXmnW/
34
+ c1NaMRdxy999hmRGzUSFjozcCwxpy/LwabxtdXwXgSay4mQ32EDjqR1TixS1+smp
35
+ 8C/NCWgpIfzpHGJsjvmH2wAfKtTTqB9CVKLCWEnCHyCaRVuKkrKjqhYCdmMBqCws
36
+ JkxfQWC+jBVeG9ZtPhQgZpfhvh+6hMhraUYRQ6XGyvBqEUe+yo6DKIT3MtGE2+CP
37
+ eX9i9ZWBydWb8/rvmwmX2kkcBbX0hZS1rcR593hGc61JR6lvkGYQ2MYskBveyaxt
38
+ Q2K9NVun/S785AP05vKkXZEFYxqG6EW012U4oLcFl5MySFajYXRYbuUpH6AY+HP8
39
+ voD0MPg1DssDLKwXyt1eKD/+Fq0bFWhwVM/1XiAXL7lyYUyOq24KHgQ2Csg=
40
+ -----END CERTIFICATE-----
41
+ date: 2022-08-28 00:00:00.000000000 Z
12
42
  dependencies:
13
43
  - !ruby/object:Gem::Dependency
14
44
  name: async-await
@@ -109,7 +139,7 @@ dependencies:
109
139
  - !ruby/object:Gem::Version
110
140
  version: '0'
111
141
  - !ruby/object:Gem::Dependency
112
- name: bundler
142
+ name: bake-test
113
143
  requirement: !ruby/object:Gem::Requirement
114
144
  requirements:
115
145
  - - ">="
@@ -123,7 +153,7 @@ dependencies:
123
153
  - !ruby/object:Gem::Version
124
154
  version: '0'
125
155
  - !ruby/object:Gem::Dependency
126
- name: covered
156
+ name: bundler
127
157
  requirement: !ruby/object:Gem::Requirement
128
158
  requirements:
129
159
  - - ">="
@@ -137,33 +167,33 @@ dependencies:
137
167
  - !ruby/object:Gem::Version
138
168
  version: '0'
139
169
  - !ruby/object:Gem::Dependency
140
- name: rake
170
+ name: covered
141
171
  requirement: !ruby/object:Gem::Requirement
142
172
  requirements:
143
173
  - - "~>"
144
174
  - !ruby/object:Gem::Version
145
- version: '10.0'
175
+ version: '0.16'
146
176
  type: :development
147
177
  prerelease: false
148
178
  version_requirements: !ruby/object:Gem::Requirement
149
179
  requirements:
150
180
  - - "~>"
151
181
  - !ruby/object:Gem::Version
152
- version: '10.0'
182
+ version: '0.16'
153
183
  - !ruby/object:Gem::Dependency
154
- name: rspec
184
+ name: sus
155
185
  requirement: !ruby/object:Gem::Requirement
156
186
  requirements:
157
187
  - - "~>"
158
188
  - !ruby/object:Gem::Version
159
- version: '3.0'
189
+ version: '0.12'
160
190
  type: :development
161
191
  prerelease: false
162
192
  version_requirements: !ruby/object:Gem::Requirement
163
193
  requirements:
164
194
  - - "~>"
165
195
  - !ruby/object:Gem::Version
166
- version: '3.0'
196
+ version: '0.12'
167
197
  description:
168
198
  email:
169
199
  executables:
@@ -178,11 +208,14 @@ files:
178
208
  - lib/benchmark/http/command/hammer.rb
179
209
  - lib/benchmark/http/command/latency.rb
180
210
  - lib/benchmark/http/command/spider.rb
211
+ - lib/benchmark/http/command/wait.rb
181
212
  - lib/benchmark/http/links_filter.rb
182
213
  - lib/benchmark/http/seconds.rb
183
214
  - lib/benchmark/http/spider.rb
184
215
  - lib/benchmark/http/statistics.rb
185
216
  - lib/benchmark/http/version.rb
217
+ - license.md
218
+ - readme.md
186
219
  homepage: https://github.com/socketry/benchmark-http
187
220
  licenses:
188
221
  - MIT
@@ -202,7 +235,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
202
235
  - !ruby/object:Gem::Version
203
236
  version: '0'
204
237
  requirements: []
205
- rubygems_version: 3.2.32
238
+ rubygems_version: 3.3.7
206
239
  signing_key:
207
240
  specification_version: 4
208
241
  summary: An asynchronous benchmark toolbox for modern HTTP servers.
metadata.gz.sig ADDED
Binary file