nchan_tools 0.1.4 → 0.1.5

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: 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