dripdrop 0.3.1 → 0.4.0
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.
- data/README.md +23 -28
- data/VERSION +1 -1
- data/dripdrop.gemspec +25 -3
- data/example/combined.rb +33 -0
- data/example/pubsub.rb +7 -15
- data/example/stats_app/core.rb +113 -0
- data/example/stats_app/public/.sass-cache/b48b4299d80c05f528daf63fe51d85e5e3c10d98/stats.scssc +0 -0
- data/example/stats_app/public/backbone.js +16 -0
- data/example/stats_app/public/build_templates.rb +5 -0
- data/example/stats_app/public/json2.js +482 -0
- data/example/stats_app/public/protovis-r3.2.js +277 -0
- data/example/stats_app/public/stats.css +5 -0
- data/example/stats_app/public/stats.haml +61 -0
- data/example/stats_app/public/stats.html +26 -0
- data/example/stats_app/public/stats.js +113 -0
- data/example/stats_app/public/stats.scss +10 -0
- data/example/stats_app/public/underscore.js +17 -0
- data/example/xreq_xrep.rb +9 -11
- data/js/dripdrop.js +6 -2
- data/lib/dripdrop/handlers/base.rb +18 -0
- data/lib/dripdrop/handlers/http.rb +18 -18
- data/lib/dripdrop/handlers/websockets.rb +33 -26
- data/lib/dripdrop/handlers/zeromq.rb +30 -24
- data/lib/dripdrop/message.rb +5 -0
- data/lib/dripdrop/node/nodelet.rb +29 -0
- data/lib/dripdrop/node.rb +103 -25
- data/spec/gimite-websocket.rb +442 -0
- data/spec/message_spec.rb +5 -0
- data/spec/node/http_spec.rb +2 -8
- data/spec/node/nodelet_spec.rb +57 -0
- data/spec/node/routing_spec.rb +68 -0
- data/spec/node/websocket_spec.rb +88 -0
- data/spec/node/zmq_pushpull_spec.rb +2 -6
- data/spec/node/zmq_xrepxreq_spec.rb +24 -24
- data/spec/node_spec.rb +0 -1
- data/spec/spec_helper.rb +17 -3
- metadata +27 -5
- data/js/jack.js +0 -876
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "nodelets" do
|
4
|
+
before(:all) do
|
5
|
+
nodelets = {}
|
6
|
+
|
7
|
+
@node = run_reactor do
|
8
|
+
routes_for :distributor do
|
9
|
+
route :output, :zmq_push, rand_addr, :bind
|
10
|
+
end
|
11
|
+
routes_for :worker_cluster do
|
12
|
+
route :worker1, :zmq_pull, distributor_output.address, :connect
|
13
|
+
route :worker2, :zmq_pull, distributor_output.address, :connect
|
14
|
+
end
|
15
|
+
|
16
|
+
nodelet :distributor do |d|
|
17
|
+
nodelets[:distributor] = d
|
18
|
+
end
|
19
|
+
|
20
|
+
nodelet :worker_cluster do |wc|
|
21
|
+
nodelets[:worker_cluster] = wc
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
@nodelets = nodelets
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should create the nodelets" do
|
29
|
+
@nodelets.length.should == 2
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should pass a DripDrop::Node::Nodelet to the block" do
|
33
|
+
@nodelets.values.each do |nlet|
|
34
|
+
nlet.should be_instance_of(DripDrop::Node::Nodelet)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should give access to the full routing table to nodelets" do
|
39
|
+
@node.routing.each do |route_name,handler|
|
40
|
+
@nodelets.values.each do |nlet|
|
41
|
+
nlet.send(route_name).should == handler
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should define prefix-less versions of nodelet specific routes" do
|
47
|
+
{
|
48
|
+
@nodelets[:worker_cluster] => {:worker1 => :worker_cluster_worker1,
|
49
|
+
:worker2 => :worker_cluster_worker2},
|
50
|
+
@nodelets[:distributor] => {:output => :distributor_output}
|
51
|
+
}.each do |nlet, mapping|
|
52
|
+
mapping.each do |short,long|
|
53
|
+
nlet.send(short).should == nlet.send(long)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "routing" do
|
4
|
+
shared_examples_for "all routing" do
|
5
|
+
it "should define all routes in the table" do
|
6
|
+
@expected_routing.keys.each do |route_name|
|
7
|
+
@node.routing.keys.should include(route_name)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should define a handler in the routing table for each route" do
|
12
|
+
@expected_routing.keys.each do |route_name|
|
13
|
+
@node.routing[route_name].should be_kind_of(DripDrop::BaseHandler)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should define a singleton method for each entry in the routing table" do
|
18
|
+
@expected_routing.keys.each do |route_name|
|
19
|
+
@node.send(route_name).should == @node.routing[route_name]
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should create handlers with the correct properties" do
|
24
|
+
@expected_routing.each do |route_name,expected_props|
|
25
|
+
handler = @node.send(route_name)
|
26
|
+
handler.class.should == expected_props[:class]
|
27
|
+
handler.socket_ctype.should == expected_props[:socket_ctype]
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
context "with no groups" do
|
33
|
+
before(:all) do
|
34
|
+
@expected_routing = {
|
35
|
+
:distributor => {:class => DripDrop::ZMQPushHandler, :socket_ctype => :bind},
|
36
|
+
:worker1 => {:class => DripDrop::ZMQPullHandler, :socket_ctype => :connect},
|
37
|
+
:worker2 => {:class => DripDrop::ZMQPullHandler, :socket_ctype => :connect}
|
38
|
+
}
|
39
|
+
@node = run_reactor do
|
40
|
+
route :distributor, :zmq_push, rand_addr, :bind
|
41
|
+
route :worker1, :zmq_pull, distributor.address, :connect
|
42
|
+
route :worker2, :zmq_pull, distributor.address, :connect
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
it_should_behave_like "all routing"
|
47
|
+
end
|
48
|
+
context "with groups" do
|
49
|
+
before(:all) do
|
50
|
+
@expected_routing = {
|
51
|
+
:distributor_output => {:class => DripDrop::ZMQPushHandler, :socket_ctype => :bind},
|
52
|
+
:worker_cluster_worker1 => {:class => DripDrop::ZMQPullHandler, :socket_ctype => :connect},
|
53
|
+
:worker_cluster_worker2 => {:class => DripDrop::ZMQPullHandler, :socket_ctype => :connect}
|
54
|
+
}
|
55
|
+
@node = run_reactor do
|
56
|
+
routes_for :distributor do
|
57
|
+
route :output, :zmq_push, rand_addr, :bind
|
58
|
+
end
|
59
|
+
routes_for :worker_cluster do
|
60
|
+
route :worker1, :zmq_pull, distributor_output.address, :connect
|
61
|
+
route :worker2, :zmq_pull, distributor_output.address, :connect
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
it_should_behave_like "all routing"
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "websockets" do
|
4
|
+
def websockets_send_messages(to_send,&block)
|
5
|
+
received = []
|
6
|
+
responses = []
|
7
|
+
server = nil
|
8
|
+
|
9
|
+
open_message = DripDrop::Message.new('open', :body => 'test')
|
10
|
+
open_received = false
|
11
|
+
|
12
|
+
close_occured = false
|
13
|
+
|
14
|
+
error_occured = false
|
15
|
+
|
16
|
+
@node = run_reactor(1) do
|
17
|
+
addr = rand_addr('ws')
|
18
|
+
|
19
|
+
server = websocket(addr)
|
20
|
+
server.on_open do |conn|
|
21
|
+
conn.send_message(open_message)
|
22
|
+
end.on_recv do |message,conn|
|
23
|
+
received << message
|
24
|
+
conn.send_message(message)
|
25
|
+
end.on_close do |conn|
|
26
|
+
close_occured = true
|
27
|
+
end.on_error do |conn|
|
28
|
+
error_occured = true
|
29
|
+
end
|
30
|
+
|
31
|
+
EM.defer do
|
32
|
+
client = WebSocket.new(addr)
|
33
|
+
open_received = DripDrop::Message.decode_json(client.receive)
|
34
|
+
to_send.each do |message|
|
35
|
+
client.send(message.json_encoded)
|
36
|
+
end
|
37
|
+
|
38
|
+
recvd_count = 0
|
39
|
+
while recvd_count < to_send.length && (message = client.receive)
|
40
|
+
responses << DripDrop::Message.decode_json(message)
|
41
|
+
recvd_count += 1
|
42
|
+
end
|
43
|
+
client.close
|
44
|
+
end
|
45
|
+
|
46
|
+
zmq_subscribe(rand_addr, :bind) {} #Keep zmqmachine happy
|
47
|
+
end
|
48
|
+
|
49
|
+
{:received => received, :responses => responses,
|
50
|
+
:open_message => open_message, :open_received => open_received,
|
51
|
+
:close_occured => close_occured, :error_occured => error_occured,
|
52
|
+
:handlers => {:server => server }}
|
53
|
+
end
|
54
|
+
describe "basic sending and receiving" do
|
55
|
+
before(:all) do
|
56
|
+
@sent = []
|
57
|
+
10.times {|i| @sent << DripDrop::Message.new("test-#{i}")}
|
58
|
+
@ws_info = websockets_send_messages(@sent)
|
59
|
+
end
|
60
|
+
|
61
|
+
it "should receive all sent messages" do
|
62
|
+
recvd_names = @ws_info[:received].map(&:name).inject(Set.new) {|memo,rn| memo << rn}
|
63
|
+
@sent.map(&:name).each {|sn| recvd_names.should include(sn)}
|
64
|
+
end
|
65
|
+
|
66
|
+
it "should return to the client as many responses as sent messages" do
|
67
|
+
@ws_info[:responses].length.should == @sent.length
|
68
|
+
end
|
69
|
+
|
70
|
+
it "should return to the client an identical message to that which was sent" do
|
71
|
+
@ws_info[:received].zip(@ws_info[:responses]).each do |recvd,resp|
|
72
|
+
recvd.name.should == resp.name
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
it "should generate an on open message" do
|
77
|
+
@ws_info[:open_received].to_hash.should == @ws_info[:open_message].to_hash
|
78
|
+
end
|
79
|
+
|
80
|
+
it "should generate a close event" do
|
81
|
+
@ws_info[:close_occured].should be_true
|
82
|
+
end
|
83
|
+
|
84
|
+
it "should not generate an error event" do
|
85
|
+
@ws_info[:error_occured].should be_false
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -6,7 +6,7 @@ describe "zmq push/pull" do
|
|
6
6
|
push = nil
|
7
7
|
pull = nil
|
8
8
|
|
9
|
-
@
|
9
|
+
@node = run_reactor do
|
10
10
|
addr = rand_addr
|
11
11
|
|
12
12
|
push = zmq_push(addr, :bind)
|
@@ -26,11 +26,7 @@ describe "zmq push/pull" do
|
|
26
26
|
|
27
27
|
to_send.each {|message| push.send_message(message)}
|
28
28
|
end
|
29
|
-
|
30
|
-
@ddn.start
|
31
|
-
sleep 0.1
|
32
|
-
@ddn.stop rescue nil
|
33
|
-
|
29
|
+
|
34
30
|
{:responses => responses, :handlers => { :push => push, :pull => [pull] }}
|
35
31
|
end
|
36
32
|
describe "basic sending and receiving" do
|
@@ -2,70 +2,73 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe "zmq xreq/xrep" do
|
4
4
|
def xr_tranceive_messages(to_send,&block)
|
5
|
-
|
5
|
+
recvd = []
|
6
6
|
req = nil
|
7
7
|
rep = nil
|
8
8
|
|
9
|
-
@
|
9
|
+
@node = run_reactor do
|
10
10
|
addr = rand_addr
|
11
11
|
|
12
12
|
rep = zmq_xrep(addr, :bind)
|
13
13
|
req = zmq_xreq(addr, :connect)
|
14
14
|
|
15
|
-
rep.on_recv do |message,
|
16
|
-
|
17
|
-
responses << {:identities => identities, :seq => seq, :message => message}
|
15
|
+
rep.on_recv do |message,response|
|
16
|
+
recvd << {:message => message, :response => response}
|
18
17
|
end
|
19
18
|
|
20
19
|
to_send.each {|message| req.send_message(message)}
|
21
20
|
end
|
22
21
|
|
23
|
-
|
24
|
-
sleep 0.1
|
25
|
-
@ddn.stop rescue nil
|
26
|
-
|
27
|
-
{:responses => responses, :handlers => {:req => req, :rep => rep}}
|
22
|
+
{:recvd => recvd, :handlers => {:req => req, :rep => rep}}
|
28
23
|
end
|
29
24
|
describe "basic sending and receiving" do
|
30
25
|
before(:all) do
|
31
26
|
@sent = []
|
32
27
|
10.times {|i| @sent << DripDrop::Message.new("test-#{i}")}
|
33
28
|
xr_info = xr_tranceive_messages(@sent)
|
34
|
-
@
|
29
|
+
@recvd = xr_info[:recvd]
|
35
30
|
@req_handler = xr_info[:handlers][:req]
|
36
31
|
@rep_handler = xr_info[:handlers][:rep]
|
37
32
|
end
|
38
33
|
|
39
34
|
it "should receive all sent messages in order" do
|
40
|
-
@sent.zip(@
|
41
|
-
sent.name.should ==
|
35
|
+
@sent.zip(@recvd).each do |sent,recvd|
|
36
|
+
sent.name.should == recvd[:message].name
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should pass a ZMQXrepHandler::Response object to the response callback" do
|
41
|
+
@recvd.each do |recvd_item|
|
42
|
+
recvd_item[:response].should be_instance_of(DripDrop::ZMQXRepHandler::Response)
|
42
43
|
end
|
43
44
|
end
|
44
45
|
|
45
46
|
it "should have a monotonically incrementing seq for responses" do
|
46
47
|
last_seq = 0
|
47
|
-
@
|
48
|
-
|
49
|
-
last_seq =
|
48
|
+
@recvd.each do |recvd_item|
|
49
|
+
recvd_item[:response].seq.should == last_seq + 1
|
50
|
+
last_seq = recvd_item[:response].seq
|
50
51
|
end
|
51
52
|
end
|
52
53
|
|
53
54
|
it "should include the identity of the sending socket" do
|
54
|
-
@
|
55
|
+
@recvd.each do |recvd_item|
|
56
|
+
recvd_item[:response].identities.should_not be_nil
|
57
|
+
end
|
55
58
|
end
|
56
59
|
|
57
60
|
it "should send responses back to the proper xreq sender" do
|
58
61
|
received_count = 0
|
59
62
|
|
60
|
-
|
63
|
+
run_reactor(0.2) do
|
61
64
|
addr = rand_addr
|
62
65
|
|
63
66
|
rep = zmq_xrep(addr, :bind)
|
64
67
|
req1 = zmq_xreq(addr, :connect)
|
65
68
|
req2 = zmq_xreq(addr, :connect)
|
66
69
|
|
67
|
-
rep.on_recv do |message,
|
68
|
-
|
70
|
+
rep.on_recv do |message,response|
|
71
|
+
response.send_message(message)
|
69
72
|
end
|
70
73
|
|
71
74
|
r1_msg = DripDrop::Message.new("REQ1 Message")
|
@@ -82,10 +85,7 @@ describe "zmq xreq/xrep" do
|
|
82
85
|
end
|
83
86
|
end
|
84
87
|
end
|
85
|
-
|
86
|
-
sleep 0.2
|
87
|
-
ddn.stop rescue nil #This should work...
|
88
|
-
|
88
|
+
|
89
89
|
received_count.should == 20
|
90
90
|
end
|
91
91
|
end
|
data/spec/node_spec.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
@@ -1,6 +1,20 @@
|
|
1
|
-
require File.expand_path(File.join(File.dirname(__FILE__), %w[.. lib dripdrop]))
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), %w[. .. lib dripdrop]))
|
2
2
|
Thread.abort_on_exception = true
|
3
3
|
|
4
|
-
|
5
|
-
|
4
|
+
# Used to test websocket clients.
|
5
|
+
require 'gimite-websocket'
|
6
|
+
|
7
|
+
def rand_addr(scheme='tcp')
|
8
|
+
"#{scheme}://127.0.0.1:#{rand(10_000) + 20_000}"
|
9
|
+
end
|
10
|
+
|
11
|
+
def run_reactor(time=0.1,opts={},&block)
|
12
|
+
ddn = DripDrop::Node.new(opts,&block)
|
13
|
+
ddn.start
|
14
|
+
sleep time
|
15
|
+
ddn.stop
|
16
|
+
sleep 0.1
|
17
|
+
ddn
|
6
18
|
end
|
19
|
+
|
20
|
+
|
metadata
CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 0
|
7
|
-
-
|
8
|
-
-
|
9
|
-
version: 0.
|
7
|
+
- 4
|
8
|
+
- 0
|
9
|
+
version: 0.4.0
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Andrew Cholakian
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-
|
17
|
+
date: 2010-11-15 00:00:00 -08:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -127,25 +127,43 @@ files:
|
|
127
127
|
- doc_img/topology.png
|
128
128
|
- dripdrop.gemspec
|
129
129
|
- example/agent_test.rb
|
130
|
+
- example/combined.rb
|
130
131
|
- example/http.rb
|
131
132
|
- example/pubsub.rb
|
132
133
|
- example/pushpull.rb
|
134
|
+
- example/stats_app/core.rb
|
135
|
+
- example/stats_app/public/.sass-cache/b48b4299d80c05f528daf63fe51d85e5e3c10d98/stats.scssc
|
136
|
+
- example/stats_app/public/backbone.js
|
137
|
+
- example/stats_app/public/build_templates.rb
|
138
|
+
- example/stats_app/public/json2.js
|
139
|
+
- example/stats_app/public/protovis-r3.2.js
|
140
|
+
- example/stats_app/public/stats.css
|
141
|
+
- example/stats_app/public/stats.haml
|
142
|
+
- example/stats_app/public/stats.html
|
143
|
+
- example/stats_app/public/stats.js
|
144
|
+
- example/stats_app/public/stats.scss
|
145
|
+
- example/stats_app/public/underscore.js
|
133
146
|
- example/subclass.rb
|
134
147
|
- example/xreq_xrep.rb
|
135
148
|
- js/dripdrop.html
|
136
149
|
- js/dripdrop.js
|
137
|
-
- js/jack.js
|
138
150
|
- js/qunit.css
|
139
151
|
- js/qunit.js
|
140
152
|
- lib/dripdrop.rb
|
141
153
|
- lib/dripdrop/agent.rb
|
154
|
+
- lib/dripdrop/handlers/base.rb
|
142
155
|
- lib/dripdrop/handlers/http.rb
|
143
156
|
- lib/dripdrop/handlers/websockets.rb
|
144
157
|
- lib/dripdrop/handlers/zeromq.rb
|
145
158
|
- lib/dripdrop/message.rb
|
146
159
|
- lib/dripdrop/node.rb
|
160
|
+
- lib/dripdrop/node/nodelet.rb
|
161
|
+
- spec/gimite-websocket.rb
|
147
162
|
- spec/message_spec.rb
|
148
163
|
- spec/node/http_spec.rb
|
164
|
+
- spec/node/nodelet_spec.rb
|
165
|
+
- spec/node/routing_spec.rb
|
166
|
+
- spec/node/websocket_spec.rb
|
149
167
|
- spec/node/zmq_pushpull_spec.rb
|
150
168
|
- spec/node/zmq_xrepxreq_spec.rb
|
151
169
|
- spec/node_spec.rb
|
@@ -184,8 +202,12 @@ specification_version: 3
|
|
184
202
|
summary: Evented framework for ZeroMQ and EventMachine Apps.
|
185
203
|
test_files:
|
186
204
|
- spec/spec_helper.rb
|
205
|
+
- spec/gimite-websocket.rb
|
187
206
|
- spec/node/http_spec.rb
|
207
|
+
- spec/node/routing_spec.rb
|
188
208
|
- spec/node/zmq_xrepxreq_spec.rb
|
189
209
|
- spec/node/zmq_pushpull_spec.rb
|
210
|
+
- spec/node/nodelet_spec.rb
|
211
|
+
- spec/node/websocket_spec.rb
|
190
212
|
- spec/message_spec.rb
|
191
213
|
- spec/node_spec.rb
|