cztop 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +1 -0
- data/README.md +61 -66
- data/examples/ruby_actor/actor.rb +1 -1
- data/examples/simple_req_rep/rep.rb +1 -1
- data/examples/simple_req_rep/req.rb +1 -1
- data/examples/taxi_system/README.md +3 -3
- data/examples/taxi_system/broker.rb +1 -1
- data/examples/taxi_system/client.rb +1 -1
- data/examples/taxi_system/generate_keys.rb +1 -1
- data/lib/cztop/authenticator.rb +1 -1
- data/lib/cztop/beacon.rb +1 -1
- data/lib/cztop/message.rb +8 -0
- data/lib/cztop/monitor.rb +1 -1
- data/lib/cztop/poller.rb +5 -5
- data/lib/cztop/proxy.rb +1 -1
- data/lib/cztop/version.rb +1 -1
- data/perf/README.md +8 -7
- data/perf/inproc_lat.rb +1 -1
- data/perf/inproc_thru.rb +1 -1
- data/perf/local_lat.rb +1 -1
- data/perf/remote_lat.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a0a723ca2a3e3272f97e72dbf4b90ce750d56240
|
4
|
+
data.tar.gz: 579445f67959d4cd7f8db0166adff18881d01273
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0431bec1dd537a65ba20467226cb430a3affb229319da0aaefaf2d114e72a613a3f72fc579e43c8449ec0ccb3e473e7ef9e65b8b8ddb1e77d501b63fc9d4be8f
|
7
|
+
data.tar.gz: 0ae5624063f633046af71f27123b789bf1d547f713f6c87a2050c752c49f722ad30b03867ea754bf46a1943df7b7d05ec2e0cf18155c84730fcb624ad875ebbb
|
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -64,6 +64,7 @@ Here are some some of the goals I have/had in mind for this library:
|
|
64
64
|
- [x] provide a portable Z85 implementation
|
65
65
|
* unlike [fpesce/z85](https://github.com/fpesce/z85), which is a C extension
|
66
66
|
- [ ] use it to replace the [Celluloid::ZMQ](https://github.com/celluloid/celluloid-zmq) part of [Celluloid](https://github.com/celluloid/celluloid)
|
67
|
+
* [celluloid/celluloid-zmq#56](https://github.com/celluloid/celluloid-zmq/issues/56)
|
67
68
|
- [ ] implement some of the missing (CZMQ based) Ruby examples in the [ZMQ Guide](http://zguide.zeromq.org/page:all)
|
68
69
|
|
69
70
|
## Overview
|
@@ -72,34 +73,34 @@ Here are some some of the goals I have/had in mind for this library:
|
|
72
73
|
|
73
74
|
Here's an overview of the core classes:
|
74
75
|
|
75
|
-
* CZTop
|
76
|
-
* Actor
|
77
|
-
* Authentiator < Actor
|
78
|
-
* Beacon < Actor
|
79
|
-
* Certificate
|
80
|
-
* Config
|
81
|
-
* Frame
|
82
|
-
* Message
|
83
|
-
* Monitor < Actor
|
84
|
-
* Proxy < Actor
|
85
|
-
* Poller
|
86
|
-
* Socket
|
87
|
-
* REQ < Socket
|
88
|
-
* REP < Socket
|
89
|
-
* ROUTER < Socket
|
90
|
-
* DEALER < Socket
|
91
|
-
* PUSH < Socket
|
92
|
-
* PULL < Socket
|
93
|
-
* PUB < Socket
|
94
|
-
* SUB < Socket
|
95
|
-
* XPUB < Socket
|
96
|
-
* XSUB < Socket
|
97
|
-
* PAIR < Socket
|
98
|
-
* STREAM < Socket
|
99
|
-
* CLIENT < Socket
|
100
|
-
* SERVER < Socket
|
101
|
-
* Z85
|
102
|
-
* Padded < Z85
|
76
|
+
* [CZTop](http://www.rubydoc.info/gems/cztop/CZTop)
|
77
|
+
* [Actor](http://www.rubydoc.info/gems/cztop/CZTop)
|
78
|
+
* [Authentiator](http://www.rubydoc.info/gems/cztop/CZTop/Authenticator) < Actor
|
79
|
+
* [Beacon](http://www.rubydoc.info/gems/cztop/CZTop/Beacon) < Actor
|
80
|
+
* [Certificate](http://www.rubydoc.info/gems/cztop/CZTop/Certificate)
|
81
|
+
* [Config](http://www.rubydoc.info/gems/cztop/CZTop/Config)
|
82
|
+
* [Frame](http://www.rubydoc.info/gems/cztop/CZTop/Frame)
|
83
|
+
* [Message](http://www.rubydoc.info/gems/cztop/CZTop/Message)
|
84
|
+
* [Monitor](http://www.rubydoc.info/gems/cztop/CZTop/Monitor) < Actor
|
85
|
+
* [Proxy](http://www.rubydoc.info/gems/cztop/CZTop/Proxy) < Actor
|
86
|
+
* [Poller](http://www.rubydoc.info/gems/cztop/CZTop/Poller)
|
87
|
+
* [Socket](http://www.rubydoc.info/gems/cztop/CZTop/Socket)
|
88
|
+
* [REQ](http://www.rubydoc.info/gems/cztop/CZTop/Socket/REQ) < Socket
|
89
|
+
* [REP](http://www.rubydoc.info/gems/cztop/CZTop/Socket/REP) < Socket
|
90
|
+
* [ROUTER](http://www.rubydoc.info/gems/cztop/CZTop/Socket/ROUTER) < Socket
|
91
|
+
* [DEALER](http://www.rubydoc.info/gems/cztop/CZTop/Socket/DEALER) < Socket
|
92
|
+
* [PUSH](http://www.rubydoc.info/gems/cztop/CZTop/Socket/PUSH) < Socket
|
93
|
+
* [PULL](http://www.rubydoc.info/gems/cztop/CZTop/Socket/PULL) < Socket
|
94
|
+
* [PUB](http://www.rubydoc.info/gems/cztop/CZTop/Socket/PUB) < Socket
|
95
|
+
* [SUB](http://www.rubydoc.info/gems/cztop/CZTop/Socket/SUB) < Socket
|
96
|
+
* [XPUB](http://www.rubydoc.info/gems/cztop/CZTop/Socket/XPUB) < Socket
|
97
|
+
* [XSUB](http://www.rubydoc.info/gems/cztop/CZTop/Socket/XSUB) < Socket
|
98
|
+
* [PAIR](http://www.rubydoc.info/gems/cztop/CZTop/Socket/PAIR) < Socket
|
99
|
+
* [STREAM](http://www.rubydoc.info/gems/cztop/CZTop/Socket/STREAM) < Socket
|
100
|
+
* [CLIENT](http://www.rubydoc.info/gems/cztop/CZTop/Socket/CLIENT) < Socket
|
101
|
+
* [SERVER](http://www.rubydoc.info/gems/cztop/CZTop/Socket/SERVER) < Socket
|
102
|
+
* [Z85](http://www.rubydoc.info/gems/cztop/CZTop/Z85)
|
103
|
+
* [Padded](http://www.rubydoc.info/gems/cztop/CZTop/Z85/Padded) < Z85
|
103
104
|
|
104
105
|
More information in the [API documentation](http://www.rubydoc.info/github/paddor/cztop).
|
105
106
|
|
@@ -185,7 +186,7 @@ is tested.
|
|
185
186
|
|
186
187
|
At the time of writing, these include:
|
187
188
|
|
188
|
-
* MRI (2.3, 2.2.4, 2.1.8)
|
189
|
+
* MRI (2.3, 2.2.4, 2.1.8, 2.0.0)
|
189
190
|
* Rubinius (HEAD)
|
190
191
|
* JRuby 9000 (HEAD)
|
191
192
|
|
@@ -205,6 +206,30 @@ Or install it yourself as:
|
|
205
206
|
|
206
207
|
$ gem install cztop
|
207
208
|
|
209
|
+
## Documentation
|
210
|
+
|
211
|
+
The API should be fairly straight-forward to anyone who is familiar with CZMQ
|
212
|
+
and Ruby. The following API documentation is currently available:
|
213
|
+
|
214
|
+
* [YARD API documentation](http://www.rubydoc.info/github/paddor/cztop) (HEAD)
|
215
|
+
* [YARD API documentation](http://www.rubydoc.info/gems/cztop) (release)
|
216
|
+
|
217
|
+
Feel free to start a [wiki](https://github.com/paddor/cztop/wiki) page.
|
218
|
+
|
219
|
+
## Performance
|
220
|
+
|
221
|
+
Performance should be pretty okay since this is based on czmq-ffi-gen, which is
|
222
|
+
reasonably thin. CZTop is basically only a convenience layer on top, with some
|
223
|
+
nice error checking. But hey, it's Ruby. Don't expect 5M messages per second
|
224
|
+
with a latency of 3us.
|
225
|
+
|
226
|
+
The measured latency on my laptop ranges from ~20us to ~60us per message for
|
227
|
+
1kb messages, depending on whether transport is inproc, IPC, or TCP/IP.
|
228
|
+
|
229
|
+
Make sure you check out the
|
230
|
+
[perf](https://github.com/paddor/cztop/blob/master/perf) directory for latency
|
231
|
+
and throughput measurement scripts.
|
232
|
+
|
208
233
|
## Usage
|
209
234
|
|
210
235
|
See the [examples](https://github.com/paddor/cztop/blob/master/examples) directory for some examples. Here's a very simple one:
|
@@ -213,7 +238,7 @@ See the [examples](https://github.com/paddor/cztop/blob/master/examples) directo
|
|
213
238
|
|
214
239
|
```ruby
|
215
240
|
#!/usr/bin/env ruby
|
216
|
-
|
241
|
+
require 'cztop'
|
217
242
|
|
218
243
|
# create and bind socket
|
219
244
|
socket = CZTop::Socket::REP.new("ipc:///tmp/req_rep_example")
|
@@ -230,7 +255,7 @@ end
|
|
230
255
|
|
231
256
|
```ruby
|
232
257
|
#!/usr/bin/env ruby
|
233
|
-
|
258
|
+
require 'cztop'
|
234
259
|
|
235
260
|
# connect
|
236
261
|
socket = CZTop::Socket::REQ.new("ipc:///tmp/req_rep_example")
|
@@ -288,29 +313,6 @@ $ ./rep.rb & ./req.rb 3
|
|
288
313
|
$
|
289
314
|
```
|
290
315
|
|
291
|
-
## Documentation
|
292
|
-
|
293
|
-
The API should be fairly straight-forward to anyone who is familiar with CZMQ
|
294
|
-
and Ruby. The following API documentation is currently available:
|
295
|
-
|
296
|
-
* [YARD API documentation](http://www.rubydoc.info/github/paddor/cztop)
|
297
|
-
|
298
|
-
Feel free to start a [wiki](https://github.com/paddor/cztop/wiki) page.
|
299
|
-
|
300
|
-
## Performance
|
301
|
-
|
302
|
-
Performance should be pretty okay since this is based on czmq-ffi-gen, which is
|
303
|
-
reasonably thin. CZTop is basically only a convenience layer on top, with some
|
304
|
-
nice error checking. But hey, it's Ruby. Don't expect 5M messages per second
|
305
|
-
with a latency of 3us.
|
306
|
-
|
307
|
-
The measured latency on my laptop ranges from ~20us to ~60us per message for
|
308
|
-
1kb messages, depending on whether transport is inproc, IPC, or TCP/IP.
|
309
|
-
|
310
|
-
Make sure you check out the
|
311
|
-
[perf](https://github.com/paddor/cztop/blob/master/perf) directory for latency
|
312
|
-
and throughput measurement scripts.
|
313
|
-
|
314
316
|
## TODO
|
315
317
|
|
316
318
|
* [x] pack generated code into its own gem ([czmq-ffi-gen](https://github.com/paddor/czmq-ffi-gen))
|
@@ -373,27 +375,20 @@ and throughput measurement scripts.
|
|
373
375
|
* [x] adapt czmq-ffi-gen so it doesn't raise while `attach_function`, attach `zsys_has_curve()` instead (under same name)
|
374
376
|
* [x] adapt test suite to skip affected test examples
|
375
377
|
* [x] test on CI
|
376
|
-
* [x] port Poller to `zmq_poll()`
|
378
|
+
* [x] port [Poller](http://www.rubydoc.info/gems/cztop/CZTop/Poller) to `zmq_poll()`
|
377
379
|
* backwards compatible (`#add_reader`, `#add_writer`, `#wait` behave the same)
|
378
380
|
* but in addition, it has `#readables` and `#writables` which return arrays of sockets
|
379
|
-
* level-triggered (not sure if `zmq_poll()` itelf is, but it'll be trivial)
|
380
381
|
* could then be used in Celluloid::ZMQ
|
381
|
-
* want to use `zmq_poller()` because it can deal with CLIENT/SERVER sockets and is the future
|
382
|
-
* but can't use it because
|
383
|
-
* it doesn't allow me to get all readable/writable sockets back after one call to `#wait`
|
384
|
-
* can't just recall `#wait` with zero timeout until it says there are no
|
385
|
-
more, because ZMQ sockets (option ZMQ_FD) are edge-triggered :-(
|
386
|
-
* maybe I don't really need that functionality, though
|
387
|
-
* can't use `zpoller`, because it doesn't support polling for writing
|
388
382
|
* [ ] add `Message#to_s`
|
389
383
|
* return frame as string, if there's only one frame
|
390
384
|
* raise if there are multiple frames
|
391
385
|
* only safe to use on messages from SERVER/CLIENT sockets
|
392
386
|
* single-part messages are the future
|
387
|
+
* not sure yet
|
393
388
|
* [x] get rid of Loop
|
394
|
-
* cannot handle SERVER
|
395
|
-
* there
|
396
|
-
* Poller can be used to embed in an existing event loop (Celluloid), or make your own trivial one
|
389
|
+
* cannot handle CLIENT/SERVER sockets
|
390
|
+
* there good timer gems for Ruby
|
391
|
+
* Poller can be used to embed in an existing event loop (Celluloid), or make your own trivial one
|
397
392
|
|
398
393
|
## Contributing
|
399
394
|
|
@@ -47,7 +47,7 @@ that it cannot do so.
|
|
47
47
|
#!/usr/bin/env ruby
|
48
48
|
require 'pry'
|
49
49
|
require 'pathname'
|
50
|
-
|
50
|
+
require 'cztop'
|
51
51
|
|
52
52
|
endpoint = ENV["BROKER_ADDRESS"]
|
53
53
|
broker_cert = CZTop::Certificate.load ENV["BROKER_CERT"] # secret+public
|
@@ -157,7 +157,7 @@ requests) and prints them into the terminal.
|
|
157
157
|
|
158
158
|
```ruby
|
159
159
|
#!/usr/bin/env ruby
|
160
|
-
|
160
|
+
require 'cztop'
|
161
161
|
|
162
162
|
endpoint = ENV["BROKER_ADDRESS"]
|
163
163
|
broker_cert = CZTop::Certificate.load ENV["BROKER_CERT"] # public only
|
@@ -204,7 +204,7 @@ need to know the clients' secret keys just to authenticate them.
|
|
204
204
|
|
205
205
|
```ruby
|
206
206
|
#!/usr/bin/env ruby
|
207
|
-
|
207
|
+
require 'cztop'
|
208
208
|
require 'fileutils'
|
209
209
|
FileUtils.cd(File.dirname(__FILE__))
|
210
210
|
FileUtils.mkdir "public_keys"
|
data/lib/cztop/authenticator.rb
CHANGED
@@ -8,7 +8,7 @@ module CZTop
|
|
8
8
|
class Authenticator
|
9
9
|
include ::CZMQ::FFI
|
10
10
|
|
11
|
-
# function pointer to the
|
11
|
+
# function pointer to the +zauth()+ function
|
12
12
|
ZAUTH_FPTR = ::CZMQ::FFI.ffi_libraries.each do |dl|
|
13
13
|
fptr = dl.find_function("zauth")
|
14
14
|
break fptr if fptr
|
data/lib/cztop/beacon.rb
CHANGED
@@ -7,7 +7,7 @@ module CZTop
|
|
7
7
|
class Beacon
|
8
8
|
include ::CZMQ::FFI
|
9
9
|
|
10
|
-
# function pointer to the
|
10
|
+
# function pointer to the +zbeacon()+ function
|
11
11
|
ZBEACON_FPTR = ::CZMQ::FFI.ffi_libraries.each do |dl|
|
12
12
|
fptr = dl.find_function("zbeacon")
|
13
13
|
break fptr if fptr
|
data/lib/cztop/message.rb
CHANGED
@@ -32,6 +32,14 @@ module CZTop
|
|
32
32
|
content_size.zero?
|
33
33
|
end
|
34
34
|
|
35
|
+
# Support Ruby 2.0
|
36
|
+
unless defined?(::IO::EAGAINWaitWritable)
|
37
|
+
class ::IO::EAGAINWaitWritable < Errno::EAGAIN
|
38
|
+
end
|
39
|
+
class ::IO::EAGAINWaitReadable < Errno::EAGAIN
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
35
43
|
# Send {Message} to a {Socket} or {Actor}.
|
36
44
|
#
|
37
45
|
# @note Do NOT use this {Message} anymore afterwards. Its native
|
data/lib/cztop/monitor.rb
CHANGED
@@ -12,7 +12,7 @@ module CZTop
|
|
12
12
|
class Monitor
|
13
13
|
include ::CZMQ::FFI
|
14
14
|
|
15
|
-
# function pointer to the
|
15
|
+
# function pointer to the +zmonitor()+ function
|
16
16
|
ZMONITOR_FPTR = ::CZMQ::FFI.ffi_libraries.each do |dl|
|
17
17
|
fptr = dl.find_function("zmonitor")
|
18
18
|
break fptr if fptr
|
data/lib/cztop/poller.rb
CHANGED
@@ -7,13 +7,13 @@ module CZTop
|
|
7
7
|
# Celluloid::ZMQ::Reactor#run_once all readable/writable sockets need to be
|
8
8
|
# processed.
|
9
9
|
#
|
10
|
-
# This implementation is NOT based on zpoller
|
10
|
+
# This implementation is NOT based on CZMQ's +zpoller+. Reasons:
|
11
11
|
#
|
12
|
-
# * zpoller can only poll for reading
|
12
|
+
# * +zpoller+ can only poll for reading
|
13
13
|
#
|
14
|
-
# It's also NOT based on
|
14
|
+
# It's also NOT based on +zmq_poller()+. Reasons:
|
15
15
|
#
|
16
|
-
# * zmq_poller() doesn't exist in older versions of ZMQ < 4.2
|
16
|
+
# * +zmq_poller()+ doesn't exist in older versions of ZMQ < 4.2
|
17
17
|
#
|
18
18
|
# Possible future implementation on +zmq_poller()+ might work like this, to
|
19
19
|
# support getting an array of readable/writable sockets:
|
@@ -188,7 +188,7 @@ module CZTop
|
|
188
188
|
|
189
189
|
private
|
190
190
|
|
191
|
-
# Rebuilds the list of
|
191
|
+
# Rebuilds the list of +poll_item_t+.
|
192
192
|
# @return [void]
|
193
193
|
def rebuild
|
194
194
|
@nitems = @readers.size + @writers.size
|
data/lib/cztop/proxy.rb
CHANGED
@@ -8,7 +8,7 @@ module CZTop
|
|
8
8
|
class Proxy
|
9
9
|
include ::CZMQ::FFI
|
10
10
|
|
11
|
-
# function pointer to the
|
11
|
+
# function pointer to the +zmonitor()+ function
|
12
12
|
ZPROXY_FPTR = ::CZMQ::FFI.ffi_libraries.each do |dl|
|
13
13
|
fptr = dl.find_function("zproxy")
|
14
14
|
break fptr if fptr
|
data/lib/cztop/version.rb
CHANGED
data/perf/README.md
CHANGED
@@ -5,7 +5,7 @@ This directory contains simple performance measurement utilities:
|
|
5
5
|
- `inproc_lat.rb` measures the latency of the inproc transport
|
6
6
|
- `inproc_thr.rb` measures the throughput of the inproc transport
|
7
7
|
- `local_lat.rb` and `remote_lat.rb` measure the latency other transports
|
8
|
-
- `local_thr.rb` and `remote_thr.rb` measure the throughput other transports
|
8
|
+
- `local_thr.rb` and `remote_thr.rb` measure the throughput other transports (TODO)
|
9
9
|
|
10
10
|
## Example Output
|
11
11
|
|
@@ -15,7 +15,7 @@ On my laptop, it currently looks something like this:
|
|
15
15
|
|
16
16
|
over inproc, using 10k roundtrips of a repeatedly allocated 1kb message:
|
17
17
|
```
|
18
|
-
$ ./inproc_lat_reqrep.rb 1_000 10_000
|
18
|
+
$ bundle exec ./inproc_lat_reqrep.rb 1_000 10_000
|
19
19
|
message size: 1000 [B]
|
20
20
|
roundtrip count: 10000
|
21
21
|
elapsed time: 0.469 [s]
|
@@ -24,7 +24,7 @@ average latency: 23.439 [us]<Paste>
|
|
24
24
|
|
25
25
|
over IPC, using 10k roundtrips of a repeatedly allocated 1kb message:
|
26
26
|
```
|
27
|
-
$ ./local_lat.rb ipc:///tmp/cztop-perf 1000 1000 & ./remote_lat.rb ipc:///tmp/cztop-perf 1000 1000
|
27
|
+
$ bundle exec ./local_lat.rb ipc:///tmp/cztop-perf 1000 1000 & ./remote_lat.rb ipc:///tmp/cztop-perf 1000 1000
|
28
28
|
[3] 58043
|
29
29
|
message size: 1000 [B]
|
30
30
|
roundtrip count: 1000
|
@@ -36,6 +36,7 @@ average latency: 45.482 [us]
|
|
36
36
|
over local TCP/IP stack, using 10k roundtrips of a repeatedly allocated
|
37
37
|
1kb message:
|
38
38
|
```
|
39
|
+
$ bundle exec ./local_lat.rb tcp://127.0.0.1:55667 1000 1000 & ./remote_lat.rb tcp://127.0.0.1:55667 1000 1000
|
39
40
|
[3] 58064
|
40
41
|
message size: 1000 [B]
|
41
42
|
roundtrip count: 1000
|
@@ -49,28 +50,28 @@ average latency: 61.434 [us]
|
|
49
50
|
over inproc, with message sizes from 100 bytes to 100kb, 10,000 each:
|
50
51
|
|
51
52
|
```
|
52
|
-
$ ./inproc_thru.rb 100 10_000
|
53
|
+
$ bundle exec ./inproc_thru.rb 100 10_000
|
53
54
|
message size: 100 [B]
|
54
55
|
message count: 10000
|
55
56
|
elapsed time: 0.270 [s]
|
56
57
|
mean throughput: 37093 [msg/s]
|
57
58
|
mean throughput: 29.674 [Mb/s]
|
58
59
|
|
59
|
-
$ ./inproc_thru.rb 1_000 10_000
|
60
|
+
$ bundle exec ./inproc_thru.rb 1_000 10_000
|
60
61
|
message size: 1000 [B]
|
61
62
|
message count: 10000
|
62
63
|
elapsed time: 0.260 [s]
|
63
64
|
mean throughput: 38498 [msg/s]
|
64
65
|
mean throughput: 307.987 [Mb/s]
|
65
66
|
|
66
|
-
$ ./inproc_thru.rb 10_000 10_000
|
67
|
+
$ bundle exec ./inproc_thru.rb 10_000 10_000
|
67
68
|
message size: 10000 [B]
|
68
69
|
message count: 10000
|
69
70
|
elapsed time: 0.317 [s]
|
70
71
|
mean throughput: 31501 [msg/s]
|
71
72
|
mean throughput: 2520.102 [Mb/s]
|
72
73
|
|
73
|
-
$ ./inproc_thru.rb 100_000 10_000
|
74
|
+
$ bundle exec ./inproc_thru.rb 100_000 10_000
|
74
75
|
message size: 100000 [B]
|
75
76
|
message count: 10000
|
76
77
|
elapsed time: 0.906 [s]
|
data/perf/inproc_lat.rb
CHANGED
data/perf/inproc_thru.rb
CHANGED
data/perf/local_lat.rb
CHANGED
data/perf/remote_lat.rb
CHANGED