dripdrop 0.9.3 → 0.9.4
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 +2 -4
- data/VERSION +1 -1
- data/dripdrop.gemspec +2 -2
- data/lib/dripdrop/handlers/http.rb +5 -3
- data/lib/dripdrop/handlers/zeromq.rb +1 -1
- data/lib/dripdrop/message.rb +7 -6
- data/lib/dripdrop/node.rb +23 -21
- data/spec/message_spec.rb +4 -4
- metadata +4 -4
data/README.md
CHANGED
@@ -1,8 +1,6 @@
|
|
1
1
|
# DripDrop
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
DripDrop is ZeroMQ(using zmqmachine) + Event Machine simplified for the general use case + serialization helpers.
|
3
|
+
DripDrop is a library for structured message-passing async apps using EventMachine, ZeroMQ, and other protocols.
|
6
4
|
|
7
5
|
Here's an example of the kind of thing DripDrop makes easy, from [example/combined.rb](http://github.com/andrewvc/dripdrop/blob/master/example/combined.rb)
|
8
6
|
|
@@ -40,7 +38,7 @@ Here's an example of the kind of thing DripDrop makes easy, from [example/combin
|
|
40
38
|
end
|
41
39
|
end.start! #Start the reactor and block until complete
|
42
40
|
|
43
|
-
Note that these aren't regular ZMQ sockets, and that the HTTP server isn't a regular server.
|
41
|
+
Note that these aren't regular ZMQ sockets, and that the HTTP server isn't a regular server.They only speak and respond using DripDrop::Message formatted messages. For HTTP/WebSockets it's JSON that looks like {name: 'name', head: {}, body: anything}, for ZeroMQ it means MessagePack. There is a raw mode that you can use for other message formats, but using DripDrop::Messages makes things easier, and for some socket types (like XREQ/XREP) the predefined format is very useful in matching requests to replies.
|
44
42
|
|
45
43
|
#RDoc
|
46
44
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.9.
|
1
|
+
0.9.4
|
data/dripdrop.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{dripdrop}
|
8
|
-
s.version = "0.9.
|
8
|
+
s.version = "0.9.4"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Andrew Cholakian"]
|
12
|
-
s.date = %q{2011-02-
|
12
|
+
s.date = %q{2011-02-07}
|
13
13
|
s.description = %q{Evented framework for ZeroMQ and EventMachine Apps. }
|
14
14
|
s.email = %q{andrew@andrewvc.com}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -17,7 +17,7 @@ class DripDrop
|
|
17
17
|
|
18
18
|
def send_message(raw_msg)
|
19
19
|
msg = dd_messagify(raw_msg)
|
20
|
-
if msg.
|
20
|
+
if msg.is_a?(DripDrop::Message)
|
21
21
|
json = msg.encode_json
|
22
22
|
self.call([json])
|
23
23
|
self.succeed
|
@@ -63,6 +63,7 @@ class DripDrop
|
|
63
63
|
@uri = uri
|
64
64
|
@address = uri.to_s
|
65
65
|
@opts = opts
|
66
|
+
@message_class = @opts[:message_class] || DripDrop.default_message_class
|
66
67
|
end
|
67
68
|
|
68
69
|
def on_recv(msg_format=:dripdrop_json,&block)
|
@@ -90,11 +91,12 @@ class DripDrop
|
|
90
91
|
@uri = uri
|
91
92
|
@address = @uri.to_s
|
92
93
|
@opts = opts
|
94
|
+
@message_class = @opts[:message_class] || DripDrop.default_message_class
|
93
95
|
end
|
94
96
|
|
95
97
|
def send_message(message,&block)
|
96
98
|
dd_message = dd_messagify(message)
|
97
|
-
if dd_message.
|
99
|
+
if dd_message.is_a?(DripDrop::Message)
|
98
100
|
uri_path = @uri.path.empty? ? '/' : @uri.path
|
99
101
|
|
100
102
|
req = EM::Protocols::HttpClient.request(
|
@@ -104,7 +106,7 @@ class DripDrop
|
|
104
106
|
:content => dd_message.encode_json
|
105
107
|
)
|
106
108
|
req.callback do |response|
|
107
|
-
block.call(
|
109
|
+
block.call(@message_class.decode_json(response[:content]))
|
108
110
|
end
|
109
111
|
else
|
110
112
|
raise "Unsupported message type '#{dd_message.class}'"
|
data/lib/dripdrop/message.rb
CHANGED
@@ -3,6 +3,7 @@ require 'msgpack'
|
|
3
3
|
require 'yajl'
|
4
4
|
|
5
5
|
class DripDrop
|
6
|
+
class WrongMessageClassError < StandardError; end
|
6
7
|
# DripDrop::Message messages are exchanged between all tiers in the architecture
|
7
8
|
# A Message is composed of a name, head, and body, and should be restricted to types that
|
8
9
|
# can be readily encoded to JSON.
|
@@ -31,7 +32,7 @@ class DripDrop
|
|
31
32
|
|
32
33
|
@head = extra[:head] || extra['head'] || {}
|
33
34
|
raise ArgumentError, "Invalid head #{@head}. Head must be a hash!" unless @head.is_a?(Hash)
|
34
|
-
@head['
|
35
|
+
@head['message_class'] = self.class.to_s
|
35
36
|
|
36
37
|
@name = name
|
37
38
|
@body = extra[:body] || extra['body']
|
@@ -72,7 +73,7 @@ class DripDrop
|
|
72
73
|
|
73
74
|
def self.recreate_message(hash)
|
74
75
|
raise ArgumentError, "Message missing head: #{hash.inspect}" unless hash['head']
|
75
|
-
raise
|
76
|
+
raise DripDrop::WrongMessageClassError, "Wrong message class #{hash['head']['message_class']} for #{self.to_s}" unless hash['head']['message_class'] == self.to_s
|
76
77
|
self.from_hash(hash)
|
77
78
|
end
|
78
79
|
|
@@ -96,14 +97,14 @@ class DripDrop
|
|
96
97
|
def self.decode_json(str)
|
97
98
|
begin
|
98
99
|
json_hash = Yajl::Parser.parse(str)
|
99
|
-
rescue Yajl::
|
100
|
+
rescue Yajl::ParseError => e
|
100
101
|
puts "Could not parse msg '#{str}': #{e.message}"
|
101
102
|
return nil
|
102
103
|
end
|
103
104
|
|
104
105
|
# Keep this consistent
|
105
|
-
json_hash['head']['
|
106
|
-
json_hash['head'].delete('
|
106
|
+
json_hash['head']['message_class'] = json_hash['head']['message_class']
|
107
|
+
json_hash['head'].delete('message_class')
|
107
108
|
|
108
109
|
self.new(json_hash['name'], 'head' => json_hash['head'], :body => json_hash['body'])
|
109
110
|
end
|
@@ -132,7 +133,7 @@ class DripDrop
|
|
132
133
|
end
|
133
134
|
raise ArgumentError, "Invalid head #{head.inspect}. Head must be a hash! (args: #{args.inspect})" unless head.is_a?(Hash)
|
134
135
|
|
135
|
-
msg_class = head['
|
136
|
+
msg_class = head['message_class']
|
136
137
|
unless DripDrop::AutoMessageClass.message_subclasses.has_key?(msg_class)
|
137
138
|
raise ArgumentError, "Unknown AutoMessage message class #{msg_class}"
|
138
139
|
end
|
data/lib/dripdrop/node.rb
CHANGED
@@ -35,26 +35,7 @@ class DripDrop
|
|
35
35
|
def start
|
36
36
|
@thread = Thread.new do
|
37
37
|
EM.error_handler {|e| self.error_handler e}
|
38
|
-
EM.run
|
39
|
-
if @block
|
40
|
-
self.instance_eval(&@block)
|
41
|
-
elsif self.respond_to?(:action)
|
42
|
-
self.action
|
43
|
-
else
|
44
|
-
raise "Could not start, no block or action specified"
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
# If the reactor has started, this blocks until the thread
|
51
|
-
# running the reactor joins. This should block forever
|
52
|
-
# unless +stop+ is called.
|
53
|
-
def join
|
54
|
-
if @thread
|
55
|
-
@thread.join
|
56
|
-
else
|
57
|
-
raise "Can't join on a node that isn't yet started"
|
38
|
+
EM.run { action }
|
58
39
|
end
|
59
40
|
end
|
60
41
|
|
@@ -69,6 +50,27 @@ class DripDrop
|
|
69
50
|
EM.stop
|
70
51
|
end
|
71
52
|
|
53
|
+
# When subclassing +DripDrop::Node+ you probably want to define this method
|
54
|
+
# Otherwise it will attempt to run the @block passed into +DripDrop::Node.new+
|
55
|
+
def action
|
56
|
+
if @block
|
57
|
+
self.instance_eval(&@block)
|
58
|
+
else
|
59
|
+
raise "Could not start, no block or specified"
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
# If the reactor has started, this blocks until the thread
|
64
|
+
# running the reactor joins. This should block forever
|
65
|
+
# unless +stop+ is called.
|
66
|
+
def join
|
67
|
+
if @thread
|
68
|
+
@thread.join
|
69
|
+
else
|
70
|
+
raise "Can't join on a node that isn't yet started"
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
72
74
|
# Defines a new route. Routes are the recommended way to instantiate
|
73
75
|
# handlers. For example:
|
74
76
|
#
|
@@ -286,7 +288,7 @@ class DripDrop
|
|
286
288
|
|
287
289
|
z_addr = "#{addr_uri.scheme}://#{host_str}:#{addr_uri.port.to_i}"
|
288
290
|
h_opts = handler_opts_given(opts)
|
289
|
-
connection = EM::ZeroMQ.create @zctx, sock_type, socket_ctype, address, klass.new
|
291
|
+
connection = EM::ZeroMQ.create @zctx, sock_type, socket_ctype, address, klass.new(h_opts)
|
290
292
|
handler = connection.handler
|
291
293
|
handler.connection = connection
|
292
294
|
handler.post_setup
|
data/spec/message_spec.rb
CHANGED
@@ -28,7 +28,7 @@ describe DripDrop::Message do
|
|
28
28
|
}.should_not raise_exception
|
29
29
|
end
|
30
30
|
it "should set the head to a single key hash containing message class if nil provided" do
|
31
|
-
DripDrop::Message.new('nilhead', :head => nil).head.should == {'
|
31
|
+
DripDrop::Message.new('nilhead', :head => nil).head.should == {'message_class' => 'DripDrop::Message'}
|
32
32
|
end
|
33
33
|
it "should raise an exception if a non-hash, non-nil head is provided" do
|
34
34
|
lambda {
|
@@ -67,7 +67,7 @@ describe DripDrop::Message do
|
|
67
67
|
def create_auto_message
|
68
68
|
attrs = {
|
69
69
|
:name => 'test',
|
70
|
-
:head => {'foo' => 'bar', '
|
70
|
+
:head => {'foo' => 'bar', 'message_class' => 'SpecMessageClass'},
|
71
71
|
:body => ['foo', 'bar', 'baz']
|
72
72
|
}
|
73
73
|
|
@@ -87,10 +87,10 @@ describe DripDrop::Message do
|
|
87
87
|
end
|
88
88
|
|
89
89
|
describe "DripDrop::AutoMessageClass" do
|
90
|
-
it "should create a properly classed message based on head['
|
90
|
+
it "should create a properly classed message based on head['message_class']" do
|
91
91
|
@message.should be_a(SpecMessageClass)
|
92
92
|
end
|
93
|
-
it "should recreate a message based on head['
|
93
|
+
it "should recreate a message based on head['message_class']" do
|
94
94
|
DripDrop::AutoMessageClass.recreate_message(@message.to_hash).should be_a(SpecMessageClass)
|
95
95
|
end
|
96
96
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dripdrop
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 51
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 9
|
9
|
-
-
|
10
|
-
version: 0.9.
|
9
|
+
- 4
|
10
|
+
version: 0.9.4
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Andrew Cholakian
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-02-
|
18
|
+
date: 2011-02-07 00:00:00 -08:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|