nchan_tools 0.1.4 → 0.1.5

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: fe6f6c40e0e15751d878e26903dd3c9812919069b8f338e0463529e836c69ae2
4
- data.tar.gz: 41b7845122c2ef1792f03f8bdb9533276c2fb5b7507d53ac670b05f3eebbf2cd
3
+ metadata.gz: fc307ac259708a9a1179d17d2faeb4bf4ae9942b9f98560aac6272d849500b6f
4
+ data.tar.gz: e93c9a63ec00ea307fb80ed6b0ccfd8e174099a6fd588a53cffd3bb2147dbce8
5
5
  SHA512:
6
- metadata.gz: 34eb95c4a0ff0c54018ec9a1671880816582a3a7c3e3b0d1eca69c64349d78c119f5bec9daf240266ef3f1c6b4c04359bc3b7ee0cef746be1bfd881b210d7298
7
- data.tar.gz: be8316e86a2b32d411fb485d73658071e713dfad3396d75f649852d2158e7b1f85b40a0bce4e6d12ac296c000886ac5c518369b52f5131270fe14a40db66ca03
6
+ metadata.gz: 4d2dc2bdf4e8fc50f506453433a780b8428d66cbe0c3e9cb066198fed262abb3920d37d76d58b1d95c185f7eb0d5cb54161a1a7a9a20a8043c4a22a82bb37d6f
7
+ data.tar.gz: 5240f7aaf08af1cad360f07c43eba880bed7840aa547535d9562ce55f9f262d2e552e3e19a28aae3bb57a17e816c69f49f46ee94a5ec33efdfc4344ae8101b4f
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  require 'securerandom'
4
- require 'nchan_tools/pubsub'
4
+ require 'nchan_tools/benchmark'
5
5
  require "optparse"
6
6
  require 'timers'
7
7
  require 'json'
@@ -47,220 +47,7 @@ end
47
47
 
48
48
  urls.uniq!
49
49
 
50
- class Benchan
51
- class BenchmarkError < StandardError
52
- end
53
- def initialize(urls, init_args=nil)
54
- @urls = urls
55
- @n = urls.count
56
- @initializing = 0
57
- @ready = 0
58
- @running = 0
59
- @finished = 0
60
- @subs = []
61
- @results = {}
62
- @failed = {}
63
-
64
- @init_args = init_args
65
-
66
- @hdrh_publish = nil
67
- @hdrh_receive = nil
68
-
69
- subs = []
70
- end
71
-
72
- def run
73
- puts "connecting to #{@n} Nchan server#{@n > 1 ? "s" : ""}..."
74
- @urls.each do |url|
75
- sub = Subscriber.new(url, 1, client: :websocket, timeout: 900000, extra_headers: {"Accept" => "text/x-json-hdrhistogram"})
76
- sub.on_failure do |err|
77
- unless @results[sub]
78
- unless @results[sub.url]
79
- @failed[sub] = true
80
- abort err, sub
81
- end
82
- end
83
- false
84
- end
85
- sub.on_message do |msg|
86
- msg = msg.to_s
87
- case msg
88
- when /^READY/
89
- puts " #{sub.url} ok"
90
- @ready +=1
91
- if @ready == @n
92
- control :run
93
- puts "start benchmark..."
94
- end
95
- when /^RUNNING/
96
- puts " #{sub.url} running"
97
- when /^RESULTS\n/
98
- msg = msg[8..-1]
99
- parsed = JSON.parse msg
100
- @results[sub.url] = parsed
101
- @results[sub.url]["raw"] = msg if @results[sub.url]
102
- 1+1
103
- when /^INITIALIZING/
104
- #do nothing
105
- else
106
- raise BenchmarkError, "unexpected server response: #{msg}"
107
- end
108
- end
109
- @subs << sub
110
- sub.run
111
- sub.wait :ready, 1
112
- if @failed[sub]
113
- puts " #{sub.url} failed"
114
- else
115
- puts " #{sub.url} ok"
116
- end
117
- end
118
- return if @failed.count > 0
119
- puts "initializing benchmark..."
120
- control :init
121
- self.wait
122
- puts "finished."
123
- puts ""
124
- end
125
-
126
- def wait
127
- @subs.each &:wait
128
- end
129
-
130
- def control(msg)
131
- if @init_args && (msg.to_sym ==:init || msg.to_sym ==:initialize)
132
- msg = "#{msg.to_s} #{@init_args.map{|k,v| "#{k}=#{v}"}.join(" ")}"
133
- end
134
- @subs.each { |sub| sub.client.send_data msg.to_s }
135
- end
136
-
137
- def abort(err, src_sub = nil)
138
- puts " #{err}"
139
- @subs.each do |sub|
140
- sub.terminate unless sub == src_sub
141
- end
142
- end
143
-
144
- def hdrhistogram_stats(name, histogram)
145
- fmt = <<-END.gsub(/^ {6}/, '')
146
- %s
147
- min: %.3fms
148
- avg: %.3fms
149
- 99%%ile: %.3fms
150
- max: %.3fms
151
- stddev: %.3fms
152
- samples: %d
153
- END
154
- fmt % [ name,
155
- histogram.min, histogram.mean, histogram.percentile(99.0), histogram.max, histogram.stddev, histogram.count
156
- ]
157
- end
158
-
159
- def results
160
- @channels = 0
161
- @runtime = []
162
- @subscribers = 0
163
- @message_length = []
164
- @messages_sent = 0
165
- @messages_send_confirmed = 0
166
- @messages_send_unconfirmed = 0
167
- @messages_send_failed = 0
168
- @messages_received = 0
169
- @messages_unreceived = 0
170
- @hdrh_publish = nil
171
- @hdrh_receive = nil
172
- @results.each do |url, data|
173
- @channels += data["channels"]
174
- @runtime << data["run_time_sec"]
175
- @subscribers += data["subscribers"]
176
- @message_length << data["message_length"]
177
- @messages_sent += data["messages"]["sent"]
178
- @messages_send_confirmed += data["messages"]["send_confirmed"]
179
- @messages_send_unconfirmed += data["messages"]["send_unconfirmed"]
180
- @messages_send_failed += data["messages"]["send_failed"]
181
- @messages_received += data["messages"]["received"]
182
- @messages_unreceived += data["messages"]["unreceived"]
183
-
184
- if data["message_publishing_histogram"]
185
- hdrh = HDRHistogram.unserialize(data["message_publishing_histogram"], unit: :ms, multiplier: 0.001)
186
- if @hdrh_publish
187
- @hdrh_publish.merge! hdrh
188
- else
189
- @hdrh_publish = hdrh
190
- end
191
- end
192
- if data["message_delivery_histogram"]
193
- hdrh = HDRHistogram.unserialize(data["message_delivery_histogram"], unit: :ms, multiplier: 0.001)
194
- if @hdrh_receive
195
- @hdrh_receive.merge! hdrh
196
- else
197
- @hdrh_receive = hdrh
198
- end
199
- end
200
- end
201
-
202
- @message_length = @message_length.sum.to_f / @message_length.size
203
- @runtime = @runtime.sum.to_f / @runtime.size
204
-
205
- fmt = <<-END.gsub(/^ {6}/, '')
206
- Nchan servers: %d
207
- runtime: %d
208
- channels: %d
209
- subscribers: %d
210
- subscribers per channel: %.1f
211
- messages:
212
- length: %d
213
- sent: %d
214
- send_confirmed: %d
215
- send_unconfirmed: %d
216
- send_failed: %d
217
- received: %d
218
- unreceived: %d
219
- send rate: %.3f/sec
220
- receive rate: %.3f/sec
221
- send rate per channel: %.3f/min
222
- receive rate per subscriber: %.3f/min
223
- END
224
- out = fmt % [
225
- @n, @runtime, @channels, @subscribers, @subscribers.to_f/@channels,
226
- @message_length, @messages_sent, @messages_send_confirmed, @messages_send_unconfirmed, @messages_send_failed,
227
- @messages_received, @messages_unreceived,
228
- @messages_sent.to_f/@runtime,
229
- @messages_received.to_f/@runtime,
230
- (@messages_sent.to_f* 60)/(@runtime * @channels),
231
- (@messages_received.to_f * 60)/(@runtime * @subscribers)
232
- ]
233
-
234
- out << hdrhistogram_stats("message publishing latency", @hdrh_publish) if @hdrh_publish
235
- out << hdrhistogram_stats("message delivery latency", @hdrh_receive) if @hdrh_receive
236
-
237
- puts out
238
- end
239
-
240
- def append_csv_file(file)
241
- require "csv"
242
- write_headers = File.zero?(file)
243
- headers = %i[servers runtime channels subscribers
244
- message_length messages_sent messages_send_confirmed messages_send_unconfirmed messages_send_failed
245
- messages_send_received messages_send_unreceived
246
- messages_send_rate messages_receive_rate messages_send_rate_per_channel messages_receive_rate_per_subscriber
247
- message_publishing_response_avg message_publishing_response_99percentile message_publishing_response_stddev message_publishing_response_count
248
- message_delivery_avg message_delivery_99percentile message_delivery_stddev message_delivery_count]
249
- csv = CSV.open(file, "a", {headers: headers, write_headers: write_headers})
250
- csv << [@n, @runtime, @channels, @subscribers,
251
- @message_length, @messages_sent, @messages_send_confirmed, @messages_send_unconfirmed, @messages_send_failed,
252
- @messages_received, @messages_unreceived,
253
- @messages_sent.to_f/@runtime, @messages_received.to_f/@runtime,
254
- (@messages_sent.to_f* 60)/(@runtime * @channels), (@messages_received.to_f * 60)/(@runtime * @subscribers),
255
- @hdrh_publish.mean, @hdrh_publish.percentile(99.0), @hdrh_publish.max, @hdrh_publish.stddev, @hdrh_publish.count,
256
- @hdrh_receive.mean, @hdrh_receive.percentile(99.0), @hdrh_receive.max, @hdrh_receive.stddev, @hdrh_receive.count
257
- ]
258
- csv.flush
259
- csv.close
260
- end
261
- end
262
-
263
- benchan = Benchan.new urls, init_args
50
+ benchan = NchanTools::Benchmark.new urls, init_args
264
51
  benchan.run
265
52
  benchan.results
266
53
  benchan.append_csv_file(save_csv) if save_csv
@@ -0,0 +1,214 @@
1
+ require 'nchan_tools/pubsub'
2
+ require 'securerandom'
3
+ require 'timers'
4
+ require 'json'
5
+
6
+ module NchanTools
7
+ class Benchmark
8
+ class BenchmarkError < StandardError
9
+ end
10
+ def initialize(urls, init_args=nil)
11
+ @urls = urls
12
+ @n = urls.count
13
+ @initializing = 0
14
+ @ready = 0
15
+ @running = 0
16
+ @finished = 0
17
+ @subs = []
18
+ @results = {}
19
+ @failed = {}
20
+
21
+ @init_args = init_args
22
+
23
+ @hdrh_publish = nil
24
+ @hdrh_receive = nil
25
+
26
+ subs = []
27
+ end
28
+
29
+ def run
30
+ puts "connecting to #{@n} Nchan server#{@n > 1 ? "s" : ""}..."
31
+ @urls.each do |url|
32
+ sub = NchanTools::Subscriber.new(url, 1, client: :websocket, timeout: 900000, extra_headers: {"Accept" => "text/x-json-hdrhistogram"})
33
+ sub.on_failure do |err|
34
+ unless @results[sub]
35
+ unless @results[sub.url]
36
+ @failed[sub] = true
37
+ abort err, sub
38
+ end
39
+ end
40
+ false
41
+ end
42
+ sub.on_message do |msg|
43
+ msg = msg.to_s
44
+ case msg
45
+ when /^READY/
46
+ puts " #{sub.url} ok"
47
+ @ready +=1
48
+ if @ready == @n
49
+ control :run
50
+ puts "start benchmark..."
51
+ end
52
+ when /^RUNNING/
53
+ puts " #{sub.url} running"
54
+ when /^RESULTS\n/
55
+ msg = msg[8..-1]
56
+ parsed = JSON.parse msg
57
+ @results[sub.url] = parsed
58
+ @results[sub.url]["raw"] = msg if @results[sub.url]
59
+ 1+1
60
+ when /^INITIALIZING/
61
+ #do nothing
62
+ else
63
+ raise BenchmarkError, "unexpected server response: #{msg}"
64
+ end
65
+ end
66
+ @subs << sub
67
+ sub.run
68
+ sub.wait :ready, 1
69
+ if @failed[sub]
70
+ puts " #{sub.url} failed"
71
+ else
72
+ puts " #{sub.url} ok"
73
+ end
74
+ end
75
+ return if @failed.count > 0
76
+ puts "initializing benchmark..."
77
+ control :init
78
+ self.wait
79
+ puts "finished."
80
+ puts ""
81
+ end
82
+
83
+ def wait
84
+ @subs.each &:wait
85
+ end
86
+
87
+ def control(msg)
88
+ if @init_args && (msg.to_sym ==:init || msg.to_sym ==:initialize)
89
+ msg = "#{msg.to_s} #{@init_args.map{|k,v| "#{k}=#{v}"}.join(" ")}"
90
+ end
91
+ @subs.each { |sub| sub.client.send_data msg.to_s }
92
+ end
93
+
94
+ def abort(err, src_sub = nil)
95
+ puts " #{err}"
96
+ @subs.each do |sub|
97
+ sub.terminate unless sub == src_sub
98
+ end
99
+ end
100
+
101
+ def hdrhistogram_stats(name, histogram)
102
+ fmt = <<-END.gsub(/^ {6}/, '')
103
+ %s
104
+ min: %.3fms
105
+ avg: %.3fms
106
+ 99%%ile: %.3fms
107
+ max: %.3fms
108
+ stddev: %.3fms
109
+ samples: %d
110
+ END
111
+ fmt % [ name,
112
+ histogram.min, histogram.mean, histogram.percentile(99.0), histogram.max, histogram.stddev, histogram.count
113
+ ]
114
+ end
115
+
116
+ def results
117
+ @channels = 0
118
+ @runtime = []
119
+ @subscribers = 0
120
+ @message_length = []
121
+ @messages_sent = 0
122
+ @messages_send_confirmed = 0
123
+ @messages_send_unconfirmed = 0
124
+ @messages_send_failed = 0
125
+ @messages_received = 0
126
+ @messages_unreceived = 0
127
+ @hdrh_publish = nil
128
+ @hdrh_receive = nil
129
+ @results.each do |url, data|
130
+ @channels += data["channels"]
131
+ @runtime << data["run_time_sec"]
132
+ @subscribers += data["subscribers"]
133
+ @message_length << data["message_length"]
134
+ @messages_sent += data["messages"]["sent"]
135
+ @messages_send_confirmed += data["messages"]["send_confirmed"]
136
+ @messages_send_unconfirmed += data["messages"]["send_unconfirmed"]
137
+ @messages_send_failed += data["messages"]["send_failed"]
138
+ @messages_received += data["messages"]["received"]
139
+ @messages_unreceived += data["messages"]["unreceived"]
140
+
141
+ if data["message_publishing_histogram"]
142
+ hdrh = HDRHistogram.unserialize(data["message_publishing_histogram"], unit: :ms, multiplier: 0.001)
143
+ if @hdrh_publish
144
+ @hdrh_publish.merge! hdrh
145
+ else
146
+ @hdrh_publish = hdrh
147
+ end
148
+ end
149
+ if data["message_delivery_histogram"]
150
+ hdrh = HDRHistogram.unserialize(data["message_delivery_histogram"], unit: :ms, multiplier: 0.001)
151
+ if @hdrh_receive
152
+ @hdrh_receive.merge! hdrh
153
+ else
154
+ @hdrh_receive = hdrh
155
+ end
156
+ end
157
+ end
158
+
159
+ @message_length = @message_length.sum.to_f / @message_length.size
160
+ @runtime = @runtime.sum.to_f / @runtime.size
161
+
162
+ fmt = <<-END.gsub(/^ {6}/, '')
163
+ Nchan servers: %d
164
+ runtime: %d
165
+ channels: %d
166
+ subscribers: %d
167
+ subscribers per channel: %.1f
168
+ messages:
169
+ length: %d
170
+ sent: %d
171
+ send_confirmed: %d
172
+ send_unconfirmed: %d
173
+ send_failed: %d
174
+ received: %d
175
+ unreceived: %d
176
+ send rate: %.3f/sec
177
+ receive rate: %.3f/sec
178
+ send rate per channel: %.3f/min
179
+ receive rate per subscriber: %.3f/min
180
+ END
181
+ out = fmt % [
182
+ @n, @runtime, @channels, @subscribers, @subscribers.to_f/@channels,
183
+ @message_length, @messages_sent, @messages_send_confirmed, @messages_send_unconfirmed, @messages_send_failed,
184
+ @messages_received, @messages_unreceived,
185
+ @messages_sent.to_f/@runtime,
186
+ @messages_received.to_f/@runtime,
187
+ (@messages_sent.to_f* 60)/(@runtime * @channels),
188
+ (@messages_received.to_f * 60)/(@runtime * @subscribers)
189
+ ]
190
+
191
+ out << hdrhistogram_stats("message publishing latency", @hdrh_publish) if @hdrh_publish
192
+ out << hdrhistogram_stats("message delivery latency", @hdrh_receive) if @hdrh_receive
193
+
194
+ puts out
195
+ end
196
+
197
+ def append_csv_file(file)
198
+ require "csv"
199
+ write_headers = File.zero?(file)
200
+ headers = %i[servers runtime channels subscribers message_length messages_sent messages_send_confirmed messages_send_unconfirmed messages_send_failed messages_send_received messages_send_unreceived messages_send_rate messages_receive_rate messages_send_rate_per_channel messages_receive_rate_per_subscriber message_publishing_response_avg message_publishing_response_99percentile message_publishing_response_max message_publishing_response_stddev message_publishing_response_count message_delivery_avg message_delivery_99percentile message_delivery_max message_delivery_stddev message_delivery_count]
201
+ csv = CSV.open(file, "a", {headers: headers, write_headers: write_headers})
202
+ csv << [@n, @runtime, @channels, @subscribers,
203
+ @message_length, @messages_sent, @messages_send_confirmed, @messages_send_unconfirmed, @messages_send_failed,
204
+ @messages_received, @messages_unreceived,
205
+ @messages_sent.to_f/@runtime, @messages_received.to_f/@runtime,
206
+ (@messages_sent.to_f* 60)/(@runtime * @channels), (@messages_received.to_f * 60)/(@runtime * @subscribers),
207
+ @hdrh_publish.mean, @hdrh_publish.percentile(99.0), @hdrh_publish.max, @hdrh_publish.stddev, @hdrh_publish.count,
208
+ @hdrh_receive.mean, @hdrh_receive.percentile(99.0), @hdrh_receive.max, @hdrh_receive.stddev, @hdrh_receive.count
209
+ ]
210
+ csv.flush
211
+ csv.close
212
+ end
213
+ end
214
+ end
@@ -3,7 +3,7 @@ require 'typhoeus'
3
3
  require 'json'
4
4
  require 'oga'
5
5
  require 'yaml'
6
- require 'pry'
6
+
7
7
  require 'celluloid/current'
8
8
  require 'date'
9
9
  Typhoeus::Config.memoize = false
@@ -46,15 +46,12 @@ module URI
46
46
  u
47
47
  end
48
48
  end
49
-
50
- $seq = 0
49
+ module NchanTools
51
50
  class Message
52
51
  attr_accessor :content_type, :message, :times_seen, :etag, :last_modified, :eventsource_event
53
52
  def initialize(msg, last_modified=nil, etag=nil)
54
53
  @times_seen=1
55
54
  @message, @last_modified, @etag = msg, last_modified, etag
56
- $seq+=1
57
- @seq = $seq
58
55
  @idhist = []
59
56
  end
60
57
  def serverside_id
@@ -703,7 +700,7 @@ class Subscriber
703
700
  end
704
701
  @connected -= 1
705
702
  if @connected <= 0
706
- binding.pry unless @ws.count == 0
703
+ sleep 0.1 until @ws.count == 0
707
704
  @cooked.signal true
708
705
  end
709
706
  end
@@ -1895,3 +1892,4 @@ class Publisher
1895
1892
 
1896
1893
 
1897
1894
  end
1895
+ end
@@ -1,3 +1,3 @@
1
1
  module NchanTools
2
- VERSION = "0.1.4"
2
+ VERSION = "0.1.5"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nchan_tools
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.1.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Leo Ponomarev
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-10-06 00:00:00.000000000 Z
11
+ date: 2018-10-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: typhoeus
@@ -228,6 +228,7 @@ files:
228
228
  - exe/nchan-pub
229
229
  - exe/nchan-sub
230
230
  - lib/nchan_tools.rb
231
+ - lib/nchan_tools/benchmark.rb
231
232
  - lib/nchan_tools/pubsub.rb
232
233
  - lib/nchan_tools/version.rb
233
234
  - nchan_tools.gemspec