schleyfox-ernie 2.2.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|