schleyfox-ernie 2.2.1
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/.document +5 -0
- data/.gitignore +2 -0
- data/History.txt +40 -0
- data/LICENSE +20 -0
- data/README.md +306 -0
- data/Rakefile +67 -0
- data/VERSION.yml +5 -0
- data/bin/ernie +116 -0
- data/contrib/ebench.erl +76 -0
- data/ebin/ernie_server_app.app +2 -0
- data/elib/asset_pool.erl +155 -0
- data/elib/asset_pool_sup.erl +13 -0
- data/elib/bert.erl +69 -0
- data/elib/ernie.hrl +18 -0
- data/elib/ernie_access_logger.erl +170 -0
- data/elib/ernie_access_logger_sup.erl +15 -0
- data/elib/ernie_admin.erl +60 -0
- data/elib/ernie_config.erl +30 -0
- data/elib/ernie_native.erl +26 -0
- data/elib/ernie_server.erl +326 -0
- data/elib/ernie_server_app.erl +20 -0
- data/elib/ernie_server_sup.erl +22 -0
- data/elib/logger.erl +108 -0
- data/elib/logger_sup.erl +13 -0
- data/elib/port_wrapper.erl +65 -0
- data/ernie.gemspec +94 -0
- data/examples/example.cfg +12 -0
- data/examples/ext.erl +8 -0
- data/examples/ext.rb +39 -0
- data/examples/nat.erl +12 -0
- data/ext/Makefile +2 -0
- data/ext/extconf.rb +1 -0
- data/lib/ernie.rb +225 -0
- data/test/ernie_server_test.rb +77 -0
- data/test/ernie_test.rb +43 -0
- data/test/helper.rb +17 -0
- data/test/load.rb +18 -0
- data/test/sample/ext.rb +42 -0
- data/test/sample/sample.cfg +4 -0
- metadata +134 -0
data/examples/ext.rb
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
|
2
|
+
require 'ernie'
|
|
3
|
+
|
|
4
|
+
module Ext
|
|
5
|
+
# Add two numbers together
|
|
6
|
+
def add(a, b)
|
|
7
|
+
a + b
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def fib(n)
|
|
11
|
+
if n == 0 || n == 1
|
|
12
|
+
1
|
|
13
|
+
else
|
|
14
|
+
fib(n - 1) + fib(n - 2)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def shadow(x)
|
|
19
|
+
"ruby"
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Return the given number of bytes
|
|
23
|
+
def bytes(n)
|
|
24
|
+
'x' * n
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Sleep for +sec+ and then return :ok
|
|
28
|
+
def slow(sec)
|
|
29
|
+
sleep(sec)
|
|
30
|
+
:ok
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Throw an error
|
|
34
|
+
def error
|
|
35
|
+
raise "abandon hope!"
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
Ernie.expose(:ext, Ext)
|
data/examples/nat.erl
ADDED
data/ext/Makefile
ADDED
data/ext/extconf.rb
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# does nothing, Makefile is handwritten
|
data/lib/ernie.rb
ADDED
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
require 'rubygems'
|
|
2
|
+
require 'bert'
|
|
3
|
+
require 'logger'
|
|
4
|
+
|
|
5
|
+
class Ernie
|
|
6
|
+
class << self
|
|
7
|
+
attr_accessor :mods, :current_mod, :log
|
|
8
|
+
attr_accessor :auto_start
|
|
9
|
+
attr_accessor :count, :virgin_procline
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
self.count = 0
|
|
13
|
+
self.virgin_procline = $0
|
|
14
|
+
self.mods = {}
|
|
15
|
+
self.current_mod = nil
|
|
16
|
+
self.log = Logger.new(STDOUT)
|
|
17
|
+
self.log.level = Logger::FATAL
|
|
18
|
+
self.auto_start = true
|
|
19
|
+
|
|
20
|
+
# Record a module.
|
|
21
|
+
# +name+ is the module Symbol
|
|
22
|
+
# +block+ is the Block containing function definitions
|
|
23
|
+
#
|
|
24
|
+
# Returns nothing
|
|
25
|
+
def self.mod(name, block)
|
|
26
|
+
m = Mod.new(name)
|
|
27
|
+
self.current_mod = m
|
|
28
|
+
self.mods[name] = m
|
|
29
|
+
block.call
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Record a function.
|
|
33
|
+
# +name+ is the function Symbol
|
|
34
|
+
# +block+ is the Block to associate
|
|
35
|
+
#
|
|
36
|
+
# Returns nothing
|
|
37
|
+
def self.fun(name, block)
|
|
38
|
+
self.current_mod.fun(name, block)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Expose all public methods in a Ruby module:
|
|
42
|
+
# +name+ is the ernie module Symbol
|
|
43
|
+
# +mixin+ is the ruby module whose public methods are exposed
|
|
44
|
+
#
|
|
45
|
+
# Returns nothing
|
|
46
|
+
def self.expose(name, mixin)
|
|
47
|
+
context = Object.new
|
|
48
|
+
context.extend mixin
|
|
49
|
+
mod(name, lambda {
|
|
50
|
+
mixin.public_instance_methods.each do |meth|
|
|
51
|
+
fun(meth.to_sym, context.method(meth))
|
|
52
|
+
end
|
|
53
|
+
})
|
|
54
|
+
context
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Set the logfile to given path.
|
|
58
|
+
# +file+ is the String path to the logfile
|
|
59
|
+
#
|
|
60
|
+
# Returns nothing
|
|
61
|
+
def self.logfile(file)
|
|
62
|
+
self.log = Logger.new(file)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# Set the log level.
|
|
66
|
+
# +level+ is the Logger level (Logger::WARN, etc)
|
|
67
|
+
#
|
|
68
|
+
# Returns nothing
|
|
69
|
+
def self.loglevel(level)
|
|
70
|
+
self.log.level = level
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# Dispatch the request to the proper mod:fun.
|
|
74
|
+
# +mod+ is the module Symbol
|
|
75
|
+
# +fun+ is the function Symbol
|
|
76
|
+
# +args+ is the Array of arguments
|
|
77
|
+
#
|
|
78
|
+
# Returns the Ruby object response
|
|
79
|
+
def self.dispatch(mod, fun, args)
|
|
80
|
+
self.mods[mod] || raise(ServerError.new("No such module '#{mod}'"))
|
|
81
|
+
self.mods[mod].funs[fun] || raise(ServerError.new("No such function '#{mod}:#{fun}'"))
|
|
82
|
+
self.mods[mod].funs[fun].call(*args)
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
# Read the length header from the wire.
|
|
86
|
+
# +input+ is the IO from which to read
|
|
87
|
+
#
|
|
88
|
+
# Returns the size Integer if one was read
|
|
89
|
+
# Returns nil otherwise
|
|
90
|
+
def self.read_4(input)
|
|
91
|
+
raw = input.read(4)
|
|
92
|
+
return nil unless raw
|
|
93
|
+
raw.unpack('N').first
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
# Read a BERP from the wire and decode it to a Ruby object.
|
|
97
|
+
# +input+ is the IO from which to read
|
|
98
|
+
#
|
|
99
|
+
# Returns a Ruby object if one could be read
|
|
100
|
+
# Returns nil otherwise
|
|
101
|
+
def self.read_berp(input)
|
|
102
|
+
packet_size = self.read_4(input)
|
|
103
|
+
return nil unless packet_size
|
|
104
|
+
bert = input.read(packet_size)
|
|
105
|
+
BERT.decode(bert)
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
# Write the given Ruby object to the wire as a BERP.
|
|
109
|
+
# +output+ is the IO on which to write
|
|
110
|
+
# +ruby+ is the Ruby object to encode
|
|
111
|
+
#
|
|
112
|
+
# Returns nothing
|
|
113
|
+
def self.write_berp(output, ruby)
|
|
114
|
+
data = BERT.encode(ruby)
|
|
115
|
+
output.write([data.length].pack("N"))
|
|
116
|
+
output.write(data)
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
# Start the processing loop.
|
|
120
|
+
#
|
|
121
|
+
# Loops forever
|
|
122
|
+
def self.start
|
|
123
|
+
self.procline('starting')
|
|
124
|
+
self.log.info("(#{Process.pid}) Starting")
|
|
125
|
+
self.log.debug(self.mods.inspect)
|
|
126
|
+
|
|
127
|
+
input = IO.new(3)
|
|
128
|
+
output = IO.new(4)
|
|
129
|
+
input.sync = true
|
|
130
|
+
output.sync = true
|
|
131
|
+
|
|
132
|
+
loop do
|
|
133
|
+
self.procline('waiting')
|
|
134
|
+
iruby = self.read_berp(input)
|
|
135
|
+
self.count += 1
|
|
136
|
+
|
|
137
|
+
unless iruby
|
|
138
|
+
puts "Could not read BERP length header. Ernie server may have gone away. Exiting now."
|
|
139
|
+
self.log.info("(#{Process.pid}) Could not read BERP length header. Ernie server may have gone away. Exiting now.")
|
|
140
|
+
exit!
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
if iruby.size == 4 && iruby[0] == :call
|
|
144
|
+
mod, fun, args = iruby[1..3]
|
|
145
|
+
self.procline("#{mod}:#{fun}(#{args})")
|
|
146
|
+
self.log.info("-> " + iruby.inspect)
|
|
147
|
+
begin
|
|
148
|
+
res = self.dispatch(mod, fun, args)
|
|
149
|
+
oruby = t[:reply, res]
|
|
150
|
+
self.log.debug("<- " + oruby.inspect)
|
|
151
|
+
write_berp(output, oruby)
|
|
152
|
+
rescue ServerError => e
|
|
153
|
+
oruby = t[:error, t[:server, 0, e.class.to_s, e.message, e.backtrace]]
|
|
154
|
+
self.log.error("<- " + oruby.inspect)
|
|
155
|
+
self.log.error(e.backtrace.join("\n"))
|
|
156
|
+
write_berp(output, oruby)
|
|
157
|
+
rescue Object => e
|
|
158
|
+
oruby = t[:error, t[:user, 0, e.class.to_s, e.message, e.backtrace]]
|
|
159
|
+
self.log.error("<- " + oruby.inspect)
|
|
160
|
+
self.log.error(e.backtrace.join("\n"))
|
|
161
|
+
write_berp(output, oruby)
|
|
162
|
+
end
|
|
163
|
+
elsif iruby.size == 4 && iruby[0] == :cast
|
|
164
|
+
mod, fun, args = iruby[1..3]
|
|
165
|
+
self.procline("#{mod}:#{fun}(#{args})")
|
|
166
|
+
self.log.info("-> " + [:cast, mod, fun, args].inspect)
|
|
167
|
+
begin
|
|
168
|
+
self.dispatch(mod, fun, args)
|
|
169
|
+
rescue Object => e
|
|
170
|
+
# ignore
|
|
171
|
+
end
|
|
172
|
+
write_berp(output, t[:noreply])
|
|
173
|
+
else
|
|
174
|
+
self.procline("invalid request")
|
|
175
|
+
self.log.error("-> " + iruby.inspect)
|
|
176
|
+
oruby = t[:error, t[:server, 0, "Invalid request: #{iruby.inspect}"]]
|
|
177
|
+
self.log.error("<- " + oruby.inspect)
|
|
178
|
+
write_berp(output, oruby)
|
|
179
|
+
end
|
|
180
|
+
end
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
def self.procline(msg)
|
|
184
|
+
$0 = "ernie handler #{VERSION} (ruby) - #{self.virgin_procline} - [#{self.count}] #{msg}"[0..159]
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
def self.version
|
|
188
|
+
yml = YAML.load(File.read(File.join(File.dirname(__FILE__), *%w[.. VERSION.yml])))
|
|
189
|
+
"#{yml[:major]}.#{yml[:minor]}.#{yml[:patch]}"
|
|
190
|
+
rescue
|
|
191
|
+
'unknown'
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
VERSION = self.version
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
class Ernie::ServerError < StandardError; end
|
|
198
|
+
|
|
199
|
+
class Ernie::Mod
|
|
200
|
+
attr_accessor :name, :funs
|
|
201
|
+
|
|
202
|
+
def initialize(name)
|
|
203
|
+
self.name = name
|
|
204
|
+
self.funs = {}
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
def fun(name, block)
|
|
208
|
+
raise TypeError, "block required" if block.nil?
|
|
209
|
+
self.funs[name] = block
|
|
210
|
+
end
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
# Root level calls
|
|
214
|
+
|
|
215
|
+
def logfile(name)
|
|
216
|
+
Ernie.logfile(name)
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
def loglevel(level)
|
|
220
|
+
Ernie.loglevel(level)
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
at_exit do
|
|
224
|
+
Ernie.start if Ernie.auto_start
|
|
225
|
+
end
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
require File.dirname(__FILE__) + '/helper'
|
|
2
|
+
|
|
3
|
+
PORT = 27118
|
|
4
|
+
|
|
5
|
+
class ErnieServerTest < Test::Unit::TestCase
|
|
6
|
+
context "An Ernie Server" do
|
|
7
|
+
setup do
|
|
8
|
+
`#{ERNIE_ROOT}/bin/ernie -c #{ERNIE_ROOT}/test/sample/sample.cfg \
|
|
9
|
+
-P /tmp/ernie.pid \
|
|
10
|
+
-p #{PORT} \
|
|
11
|
+
-d`
|
|
12
|
+
@svc = BERTRPC::Service.new('localhost', PORT)
|
|
13
|
+
loop do
|
|
14
|
+
begin
|
|
15
|
+
@svc.call.ext.zeronary
|
|
16
|
+
break
|
|
17
|
+
rescue Object => e
|
|
18
|
+
sleep 0.1
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
context "call" do
|
|
24
|
+
should "handle zeronary" do
|
|
25
|
+
assert_equal :foo, @svc.call.ext.zeronary
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
should "handle unary" do
|
|
29
|
+
assert_equal 5, @svc.call.ext.unary(5)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
should "handle binary" do
|
|
33
|
+
assert_equal 7, @svc.call.ext.binary(5, 2)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
should "handle ternary" do
|
|
37
|
+
assert_equal 10, @svc.call.ext.ternary(5, 2, 3)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
should "handle massive binaries" do
|
|
41
|
+
assert_equal 8 * 1024 * 1024, @svc.call.ext.big(8 * 1024 * 1024).size
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
should "get an error on missing module" do
|
|
45
|
+
begin
|
|
46
|
+
@svc.call.failboat.mcfail(:fail)
|
|
47
|
+
fail "Expected a BERTRPC::ServerError"
|
|
48
|
+
rescue BERTRPC::ServerError => e
|
|
49
|
+
assert_equal "No such module 'failboat'", e.message
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
should "get an error on missing function" do
|
|
54
|
+
begin
|
|
55
|
+
@svc.call.ext.mcfail(:fail)
|
|
56
|
+
fail "Expected a BERTRPC::ServerError"
|
|
57
|
+
rescue BERTRPC::ServerError => e
|
|
58
|
+
assert_equal "No such function 'ext:mcfail'", e.message
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
context "cast" do
|
|
64
|
+
should "be received and return immediately" do
|
|
65
|
+
t0 = Time.now
|
|
66
|
+
assert_equal nil, @svc.cast.ext.set_state(7)
|
|
67
|
+
assert Time.now - t0 < 1
|
|
68
|
+
assert_equal 7, @svc.call.ext.get_state
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
teardown do
|
|
73
|
+
pid = File.read('/tmp/ernie.pid')
|
|
74
|
+
`kill -9 #{pid}`
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
data/test/ernie_test.rb
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
require File.dirname(__FILE__) + '/helper'
|
|
2
|
+
|
|
3
|
+
class ErnieTest < Test::Unit::TestCase
|
|
4
|
+
module TestExposingModule
|
|
5
|
+
def foo
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def bar(a, b, c=nil)
|
|
9
|
+
[a, b, c]
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
protected
|
|
13
|
+
def baz
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
private
|
|
17
|
+
def bling
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
context "expose" do
|
|
22
|
+
setup { Ernie.expose :expo, TestExposingModule }
|
|
23
|
+
teardown { Ernie.mods.clear }
|
|
24
|
+
|
|
25
|
+
should "add all public methods from the module" do
|
|
26
|
+
assert_not_nil Ernie.mods[:expo].funs[:foo]
|
|
27
|
+
assert_not_nil Ernie.mods[:expo].funs[:bar]
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
should "not expose protected methods" do
|
|
31
|
+
assert_nil Ernie.mods[:expo].funs[:baz]
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
should "not expose private methods" do
|
|
35
|
+
assert_nil Ernie.mods[:expo].funs[:bling]
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
should "dispatch to module methods properly" do
|
|
39
|
+
res = Ernie.dispatch(:expo, :bar, ['a', :b, { :fiz => 42 }])
|
|
40
|
+
assert_equal ['a', :b, { :fiz => 42 }], res
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
data/test/helper.rb
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
require 'rubygems'
|
|
2
|
+
require 'test/unit'
|
|
3
|
+
require 'shoulda'
|
|
4
|
+
|
|
5
|
+
ERNIE_ROOT = File.join(File.dirname(__FILE__), *%w[..])
|
|
6
|
+
|
|
7
|
+
$:.unshift(File.join(ERNIE_ROOT, 'lib'))
|
|
8
|
+
|
|
9
|
+
require 'ernie'
|
|
10
|
+
Ernie.auto_start = false
|
|
11
|
+
|
|
12
|
+
begin
|
|
13
|
+
require 'bertrpc'
|
|
14
|
+
rescue LoadError
|
|
15
|
+
puts "You need bertrpc gem installed to run tests."
|
|
16
|
+
exit!(1)
|
|
17
|
+
end
|
data/test/load.rb
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
require 'bertrpc'
|
|
2
|
+
|
|
3
|
+
$stdout.sync = true
|
|
4
|
+
|
|
5
|
+
threads = []
|
|
6
|
+
svc = BERTRPC::Service.new('localhost', 8000)
|
|
7
|
+
|
|
8
|
+
8.times do
|
|
9
|
+
threads << Thread.new do
|
|
10
|
+
i = 0
|
|
11
|
+
10.times { i += svc.call.calc.add(1, 2); print '.'; $stdout.flush }
|
|
12
|
+
print "(#{i})"
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
threads.each { |t| t.join }
|
|
17
|
+
|
|
18
|
+
puts
|
data/test/sample/ext.rb
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', '..', 'lib'))
|
|
2
|
+
require 'ernie'
|
|
3
|
+
|
|
4
|
+
module Ext
|
|
5
|
+
@@state = 0
|
|
6
|
+
|
|
7
|
+
def zeronary
|
|
8
|
+
:foo
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def unary(a)
|
|
12
|
+
a
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def binary(a, b)
|
|
16
|
+
a + b
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def ternary(a, b, c)
|
|
20
|
+
a + b + c
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def set_state(x)
|
|
24
|
+
@@state = x
|
|
25
|
+
sleep 5
|
|
26
|
+
nil
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def get_state
|
|
30
|
+
@@state
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def big(x)
|
|
34
|
+
'a' * x
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def cry
|
|
38
|
+
raise "abandon hope!"
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
Ernie.expose(:ext, Ext)
|
metadata
ADDED
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: schleyfox-ernie
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
prerelease: false
|
|
5
|
+
segments:
|
|
6
|
+
- 2
|
|
7
|
+
- 2
|
|
8
|
+
- 1
|
|
9
|
+
version: 2.2.1
|
|
10
|
+
platform: ruby
|
|
11
|
+
authors:
|
|
12
|
+
- Tom Preston-Werner
|
|
13
|
+
autorequire:
|
|
14
|
+
bindir: bin
|
|
15
|
+
cert_chain: []
|
|
16
|
+
|
|
17
|
+
date: 2010-03-12 00:00:00 -05:00
|
|
18
|
+
default_executable: ernie
|
|
19
|
+
dependencies:
|
|
20
|
+
- !ruby/object:Gem::Dependency
|
|
21
|
+
name: bert
|
|
22
|
+
prerelease: false
|
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
|
24
|
+
requirements:
|
|
25
|
+
- - ">="
|
|
26
|
+
- !ruby/object:Gem::Version
|
|
27
|
+
segments:
|
|
28
|
+
- 1
|
|
29
|
+
- 1
|
|
30
|
+
- 0
|
|
31
|
+
version: 1.1.0
|
|
32
|
+
type: :runtime
|
|
33
|
+
version_requirements: *id001
|
|
34
|
+
- !ruby/object:Gem::Dependency
|
|
35
|
+
name: bertrpc
|
|
36
|
+
prerelease: false
|
|
37
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
|
38
|
+
requirements:
|
|
39
|
+
- - ">="
|
|
40
|
+
- !ruby/object:Gem::Version
|
|
41
|
+
segments:
|
|
42
|
+
- 1
|
|
43
|
+
- 0
|
|
44
|
+
- 0
|
|
45
|
+
version: 1.0.0
|
|
46
|
+
type: :runtime
|
|
47
|
+
version_requirements: *id002
|
|
48
|
+
description: Ernie is an Erlang/Ruby hybrid BERT-RPC server implementation packaged as a gem.
|
|
49
|
+
email: tom@mojombo.com
|
|
50
|
+
executables:
|
|
51
|
+
- ernie
|
|
52
|
+
extensions:
|
|
53
|
+
- ext/extconf.rb
|
|
54
|
+
- ext/extconf.rb
|
|
55
|
+
extra_rdoc_files:
|
|
56
|
+
- LICENSE
|
|
57
|
+
- README.md
|
|
58
|
+
files:
|
|
59
|
+
- .document
|
|
60
|
+
- .gitignore
|
|
61
|
+
- History.txt
|
|
62
|
+
- LICENSE
|
|
63
|
+
- README.md
|
|
64
|
+
- Rakefile
|
|
65
|
+
- VERSION.yml
|
|
66
|
+
- bin/ernie
|
|
67
|
+
- contrib/ebench.erl
|
|
68
|
+
- ebin/ernie_server_app.app
|
|
69
|
+
- elib/asset_pool.erl
|
|
70
|
+
- elib/asset_pool_sup.erl
|
|
71
|
+
- elib/bert.erl
|
|
72
|
+
- elib/ernie.hrl
|
|
73
|
+
- elib/ernie_access_logger.erl
|
|
74
|
+
- elib/ernie_access_logger_sup.erl
|
|
75
|
+
- elib/ernie_admin.erl
|
|
76
|
+
- elib/ernie_config.erl
|
|
77
|
+
- elib/ernie_native.erl
|
|
78
|
+
- elib/ernie_server.erl
|
|
79
|
+
- elib/ernie_server_app.erl
|
|
80
|
+
- elib/ernie_server_sup.erl
|
|
81
|
+
- elib/logger.erl
|
|
82
|
+
- elib/logger_sup.erl
|
|
83
|
+
- elib/port_wrapper.erl
|
|
84
|
+
- ernie.gemspec
|
|
85
|
+
- examples/example.cfg
|
|
86
|
+
- examples/ext.erl
|
|
87
|
+
- examples/ext.rb
|
|
88
|
+
- examples/nat.erl
|
|
89
|
+
- ext/Makefile
|
|
90
|
+
- ext/extconf.rb
|
|
91
|
+
- lib/ernie.rb
|
|
92
|
+
- test/ernie_server_test.rb
|
|
93
|
+
- test/ernie_test.rb
|
|
94
|
+
- test/helper.rb
|
|
95
|
+
- test/load.rb
|
|
96
|
+
- test/sample/ext.rb
|
|
97
|
+
- test/sample/sample.cfg
|
|
98
|
+
has_rdoc: true
|
|
99
|
+
homepage: http://github.com/mojombo/ernie
|
|
100
|
+
licenses: []
|
|
101
|
+
|
|
102
|
+
post_install_message:
|
|
103
|
+
rdoc_options:
|
|
104
|
+
- --charset=UTF-8
|
|
105
|
+
require_paths:
|
|
106
|
+
- lib
|
|
107
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
108
|
+
requirements:
|
|
109
|
+
- - ">="
|
|
110
|
+
- !ruby/object:Gem::Version
|
|
111
|
+
segments:
|
|
112
|
+
- 0
|
|
113
|
+
version: "0"
|
|
114
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
115
|
+
requirements:
|
|
116
|
+
- - ">="
|
|
117
|
+
- !ruby/object:Gem::Version
|
|
118
|
+
segments:
|
|
119
|
+
- 0
|
|
120
|
+
version: "0"
|
|
121
|
+
requirements: []
|
|
122
|
+
|
|
123
|
+
rubyforge_project: ernie
|
|
124
|
+
rubygems_version: 1.3.6
|
|
125
|
+
signing_key:
|
|
126
|
+
specification_version: 3
|
|
127
|
+
summary: Ernie is a BERT-RPC server implementation.
|
|
128
|
+
test_files:
|
|
129
|
+
- test/ernie_server_test.rb
|
|
130
|
+
- test/ernie_test.rb
|
|
131
|
+
- test/helper.rb
|
|
132
|
+
- test/load.rb
|
|
133
|
+
- test/sample/ext.rb
|
|
134
|
+
- examples/ext.rb
|