benchmark-http 0.15.1 → 0.16.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e94467fbbb53392ece96740e56933598ed0a301f8f6a897976e0d6ed59c2b5a0
4
- data.tar.gz: e6ca7937b05e889a91cfca556b715c92724515caaa4bdbecfd523951a16d8739
3
+ metadata.gz: f4c0dd5e1f2fcaa19df57637f954b2a2e791af4f617ff3f36272b76a47bc66b7
4
+ data.tar.gz: 871e461daa3a6efe6cb943853347b3fa1913aa5a833b2973aad6e1f1e40029ba
5
5
  SHA512:
6
- metadata.gz: 172464957224504d73e77fef8139beb33d19d9fe9098b42bf92393617a3f3dcdfee05f7aace4d8909ae05e6b03d9d60405a5e971055367372ab8e989c4aea135
7
- data.tar.gz: ba6cb3332488f08e49d90e707d6333d34b56334e3bd575b4f7d9cb129b4dee75b9bc7a3a318a3be392f01a13594fd6537921bda27800aa53f58a38584da92d67
6
+ metadata.gz: 365badabf9ab7b3d8f428db0593e8d306e2c0755a6ebf61737919678873e9465d3e52c04c9ab6ec057bb2b97a7b35a44530db140266486aec8a0b3a697b1feda
7
+ data.tar.gz: 034306fa6be3ec62e6d469f45551023087e206d0ab486d71893c79de030f4f01a6f0aa44286682c5a96e26ef97e7a0ef54776f7624147ac5a53f359737a181a8
checksums.yaml.gz.sig ADDED
@@ -0,0 +1,3 @@
1
+ ��m� ��sd�b������QC��غI'<����rŖ����0����(�и�Ȕ��m��q�-0a^��� ��MȞ���I�B�i’]�+3J��G�B�o
2
+
3
+ �o"�l���t�m�b�=K�ک?VOu�O����1��J��
@@ -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
 
@@ -36,7 +21,7 @@ module Benchmark
36
21
  def filter(node)
37
22
  if node.name == 'base'
38
23
  @base = node['href']
39
- elsif node.name == 'a'
24
+ elsif node.name == 'a' and node['href'] and node['rel'] != 'nofollow'
40
25
  @links << node['href']
41
26
  end
42
27
 
@@ -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.1"
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
@@ -0,0 +1,3 @@
1
+ $2�ƿ�U잲�bT�,Wm�3�ia���!-�(O������kםDF"෨UgE��-Qtm�{�
2
+ ծ�J"�n^�~)Q7�"��1t����U����� �C0 �S�6̧5�D�x&�Jpv�X>�3k��Hv%���<�u���PV�x�����ܖԠ%v���� ���/T��i��;����M3�)� '6��\�����7냼zK��k�u�(���=x��j� ��ooy��,�œ^/
3
+ ���c��l����v����-evt�%
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.1
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: 2023-02-21 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.4.6
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