ernie 1.0.0 → 1.1.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/History.txt +5 -0
- data/Rakefile +1 -2
- data/VERSION.yml +1 -1
- data/ernie.gemspec +5 -8
- data/examples/calc.rb +4 -0
- data/lib/ernie.rb +95 -30
- data/test/ernie_server_test.rb +4 -0
- data/test/handler.rb +4 -0
- metadata +3 -13
data/History.txt
CHANGED
data/Rakefile
CHANGED
@@ -11,8 +11,7 @@ begin
|
|
11
11
|
gem.authors = ["Tom Preston-Werner"]
|
12
12
|
gem.files.include(["ext"])
|
13
13
|
gem.extensions << 'ext/extconf.rb'
|
14
|
-
gem.add_dependency('
|
15
|
-
gem.add_dependency('bert', '>= 1.0.0')
|
14
|
+
gem.add_dependency('bert', '>= 1.1.0')
|
16
15
|
gem.add_dependency('bertrpc', '>= 1.0.0')
|
17
16
|
|
18
17
|
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
data/VERSION.yml
CHANGED
data/ernie.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{ernie}
|
8
|
-
s.version = "1.
|
8
|
+
s.version = "1.1.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Tom Preston-Werner"]
|
12
|
-
s.date = %q{2009-10-
|
12
|
+
s.date = %q{2009-10-28}
|
13
13
|
s.default_executable = %q{ernie}
|
14
14
|
s.email = %q{tom@mojombo.com}
|
15
15
|
s.executables = ["ernie"]
|
@@ -66,17 +66,14 @@ Gem::Specification.new do |s|
|
|
66
66
|
s.specification_version = 3
|
67
67
|
|
68
68
|
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
69
|
-
s.add_runtime_dependency(%q<
|
70
|
-
s.add_runtime_dependency(%q<bert>, [">= 1.0.0"])
|
69
|
+
s.add_runtime_dependency(%q<bert>, [">= 1.1.0"])
|
71
70
|
s.add_runtime_dependency(%q<bertrpc>, [">= 1.0.0"])
|
72
71
|
else
|
73
|
-
s.add_dependency(%q<
|
74
|
-
s.add_dependency(%q<bert>, [">= 1.0.0"])
|
72
|
+
s.add_dependency(%q<bert>, [">= 1.1.0"])
|
75
73
|
s.add_dependency(%q<bertrpc>, [">= 1.0.0"])
|
76
74
|
end
|
77
75
|
else
|
78
|
-
s.add_dependency(%q<
|
79
|
-
s.add_dependency(%q<bert>, [">= 1.0.0"])
|
76
|
+
s.add_dependency(%q<bert>, [">= 1.1.0"])
|
80
77
|
s.add_dependency(%q<bertrpc>, [">= 1.0.0"])
|
81
78
|
end
|
82
79
|
end
|
data/examples/calc.rb
CHANGED
data/lib/ernie.rb
CHANGED
@@ -11,6 +11,11 @@ class Ernie
|
|
11
11
|
self.current_mod = nil
|
12
12
|
self.logger = nil
|
13
13
|
|
14
|
+
# Record a module.
|
15
|
+
# +name+ is the module Symbol
|
16
|
+
# +block+ is the Block containing function definitions
|
17
|
+
#
|
18
|
+
# Returns nothing
|
14
19
|
def self.mod(name, block)
|
15
20
|
m = Mod.new(name)
|
16
21
|
self.current_mod = m
|
@@ -18,69 +23,129 @@ class Ernie
|
|
18
23
|
block.call
|
19
24
|
end
|
20
25
|
|
26
|
+
# Record a function.
|
27
|
+
# +name+ is the function Symbol
|
28
|
+
# +block+ is the Block to associate
|
29
|
+
#
|
30
|
+
# Returns nothing
|
21
31
|
def self.fun(name, block)
|
22
32
|
self.current_mod.fun(name, block)
|
23
33
|
end
|
24
34
|
|
35
|
+
# Set the logfile to given path.
|
36
|
+
# +file+ is the String path to the logfile
|
37
|
+
#
|
38
|
+
# Returns nothing
|
25
39
|
def self.logfile(file)
|
26
40
|
self.logger = Logger.new(file)
|
27
41
|
end
|
28
42
|
|
43
|
+
# If logging is enabled, log the given text.
|
44
|
+
# +text+ is the String to log
|
45
|
+
#
|
46
|
+
# Returns nothing
|
29
47
|
def self.log(text)
|
30
48
|
self.logger.info(text) if self.logger
|
31
49
|
end
|
32
50
|
|
51
|
+
# Dispatch the request to the proper mod:fun.
|
52
|
+
# +mod+ is the module Symbol
|
53
|
+
# +fun+ is the function Symbol
|
54
|
+
# +args+ is the Array of arguments
|
55
|
+
#
|
56
|
+
# Returns the Ruby object response
|
33
57
|
def self.dispatch(mod, fun, args)
|
34
|
-
xargs = BERT::Decoder.convert(args)
|
35
|
-
self.log("-- " + [mod, fun, xargs].inspect)
|
36
58
|
self.mods[mod] || raise(ServerError.new("No such module '#{mod}'"))
|
37
59
|
self.mods[mod].funs[fun] || raise(ServerError.new("No such function '#{mod}:#{fun}'"))
|
38
|
-
|
39
|
-
BERT::Encoder.convert(res)
|
60
|
+
self.mods[mod].funs[fun].call(*args)
|
40
61
|
end
|
41
62
|
|
63
|
+
# Read the length header from the wire.
|
64
|
+
# +input+ is the IO from which to read
|
65
|
+
#
|
66
|
+
# Returns the size Integer if one was read
|
67
|
+
# Returns nil otherwise
|
68
|
+
def self.read_4(input)
|
69
|
+
raw = input.read(4)
|
70
|
+
return nil unless raw
|
71
|
+
raw.unpack('N').first
|
72
|
+
end
|
73
|
+
|
74
|
+
# Read a BERP from the wire and decode it to a Ruby object.
|
75
|
+
# +input+ is the IO from which to read
|
76
|
+
#
|
77
|
+
# Returns a Ruby object if one could be read
|
78
|
+
# Returns nil otherwise
|
79
|
+
def self.read_berp(input)
|
80
|
+
packet_size = self.read_4(input)
|
81
|
+
return nil unless packet_size
|
82
|
+
bert = input.read(packet_size)
|
83
|
+
BERT.decode(bert)
|
84
|
+
end
|
85
|
+
|
86
|
+
# Write the given Ruby object to the wire as a BERP.
|
87
|
+
# +output+ is the IO on which to write
|
88
|
+
# +ruby+ is the Ruby object to encode
|
89
|
+
#
|
90
|
+
# Returns nothing
|
91
|
+
def self.write_berp(output, ruby)
|
92
|
+
data = BERT.encode(ruby)
|
93
|
+
output.write([data.length].pack("N"))
|
94
|
+
output.write(data)
|
95
|
+
end
|
96
|
+
|
97
|
+
# Start the processing loop.
|
98
|
+
#
|
99
|
+
# Loops forever
|
42
100
|
def self.start
|
43
101
|
self.log("Starting")
|
44
102
|
self.log(self.mods.inspect)
|
45
|
-
|
46
|
-
|
47
|
-
|
103
|
+
|
104
|
+
input = IO.new(3)
|
105
|
+
output = IO.new(4)
|
106
|
+
input.sync = true
|
107
|
+
output.sync = true
|
108
|
+
|
109
|
+
loop do
|
110
|
+
iruby = self.read_berp(input)
|
111
|
+
unless iruby
|
112
|
+
puts "Could not read BERP length header. Ernie server may have gone away. Exiting now."
|
113
|
+
exit!
|
114
|
+
end
|
115
|
+
|
116
|
+
if iruby.size == 4 && iruby[0] == :call
|
117
|
+
mod, fun, args = iruby[1..3]
|
118
|
+
self.log("-> " + iruby.inspect)
|
48
119
|
begin
|
49
120
|
res = self.dispatch(mod, fun, args)
|
50
|
-
|
51
|
-
self.log("<- " +
|
52
|
-
|
121
|
+
oruby = t[:reply, res]
|
122
|
+
self.log("<- " + oruby.inspect)
|
123
|
+
write_berp(output, oruby)
|
53
124
|
rescue ServerError => e
|
54
|
-
|
55
|
-
self.log("<- " +
|
125
|
+
oruby = t[:error, t[:server, 0, e.class.to_s, e.message, e.backtrace]]
|
126
|
+
self.log("<- " + oruby.inspect)
|
56
127
|
self.log(e.backtrace.join("\n"))
|
57
|
-
|
128
|
+
write_berp(output, oruby)
|
58
129
|
rescue Object => e
|
59
|
-
|
60
|
-
self.log("<- " +
|
130
|
+
oruby = t[:error, t[:user, 0, e.class.to_s, e.message, e.backtrace]]
|
131
|
+
self.log("<- " + oruby.inspect)
|
61
132
|
self.log(e.backtrace.join("\n"))
|
62
|
-
|
133
|
+
write_berp(output, oruby)
|
63
134
|
end
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
f.when([:cast, Symbol, Symbol, Array]) do |mod, fun, args|
|
135
|
+
elsif iruby.size == 4 && iruby[0] == :cast
|
136
|
+
mod, fun, args = iruby[1..3]
|
68
137
|
self.log("-> " + [:cast, mod, fun, args].inspect)
|
69
138
|
begin
|
70
139
|
self.dispatch(mod, fun, args)
|
71
140
|
rescue Object => e
|
72
141
|
# ignore
|
73
142
|
end
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
xres = [:error, [:server, 0, "Invalid request: #{any.inspect}"]]
|
81
|
-
self.log("<- " + xres.inspect)
|
82
|
-
f.send!(xres)
|
83
|
-
f.receive_loop
|
143
|
+
write_berp(output, t[:noreply])
|
144
|
+
else
|
145
|
+
self.log("-> " + iruby.inspect)
|
146
|
+
oruby = t[:error, t[:server, 0, "Invalid request: #{iruby.inspect}"]]
|
147
|
+
self.log("<- " + oruby.inspect)
|
148
|
+
write_berp(output, oruby)
|
84
149
|
end
|
85
150
|
end
|
86
151
|
end
|
data/test/ernie_server_test.rb
CHANGED
@@ -37,6 +37,10 @@ class ErnieServerTest < Test::Unit::TestCase
|
|
37
37
|
assert_equal 10, @svc.call.test.ternary(5, 2, 3)
|
38
38
|
end
|
39
39
|
|
40
|
+
should "handle massive binaries" do
|
41
|
+
assert_equal 8 * 1024 * 1024, @svc.call.test.big(8 * 1024 * 1024).size
|
42
|
+
end
|
43
|
+
|
40
44
|
should "get an error on missing module" do
|
41
45
|
begin
|
42
46
|
@svc.call.failboat.mcfail(:fail)
|
data/test/handler.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ernie
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tom Preston-Werner
|
@@ -9,19 +9,9 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-10-
|
12
|
+
date: 2009-10-28 00:00:00 -07:00
|
13
13
|
default_executable: ernie
|
14
14
|
dependencies:
|
15
|
-
- !ruby/object:Gem::Dependency
|
16
|
-
name: erlectricity
|
17
|
-
type: :runtime
|
18
|
-
version_requirement:
|
19
|
-
version_requirements: !ruby/object:Gem::Requirement
|
20
|
-
requirements:
|
21
|
-
- - ">="
|
22
|
-
- !ruby/object:Gem::Version
|
23
|
-
version: 1.1.0
|
24
|
-
version:
|
25
15
|
- !ruby/object:Gem::Dependency
|
26
16
|
name: bert
|
27
17
|
type: :runtime
|
@@ -30,7 +20,7 @@ dependencies:
|
|
30
20
|
requirements:
|
31
21
|
- - ">="
|
32
22
|
- !ruby/object:Gem::Version
|
33
|
-
version: 1.
|
23
|
+
version: 1.1.0
|
34
24
|
version:
|
35
25
|
- !ruby/object:Gem::Dependency
|
36
26
|
name: bertrpc
|