bertrem 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +23 -0
- data/README.md +120 -0
- data/Rakefile +24 -0
- data/VERSION +1 -0
- data/bertem.gemspec +52 -0
- data/lib/bertrem.rb +18 -0
- data/lib/bertrem/action.rb +35 -0
- data/lib/bertrem/client.rb +105 -0
- data/lib/bertrem/mod.rb +18 -0
- data/lib/bertrem/server.rb +164 -0
- metadata +87 -0
data/LICENSE
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
Copyright (c) 2009 Benjamin Black
|
2
|
+
|
3
|
+
Derived in part from work that is
|
4
|
+
Copyright (c) 2009 Tom Preston-Werner
|
5
|
+
|
6
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
7
|
+
a copy of this software and associated documentation files (the
|
8
|
+
"Software"), to deal in the Software without restriction, including
|
9
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
10
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
11
|
+
permit persons to whom the Software is furnished to do so, subject to
|
12
|
+
the following conditions:
|
13
|
+
|
14
|
+
The above copyright notice and this permission notice shall be
|
15
|
+
included in all copies or substantial portions of the Software.
|
16
|
+
|
17
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
18
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
19
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
20
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
21
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
22
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
23
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,120 @@
|
|
1
|
+
BERTREM
|
2
|
+
======
|
3
|
+
|
4
|
+
By Benjamin Black (b@b3k.us)
|
5
|
+
|
6
|
+
BERTREM is a BERT-RPC client and server implementation that uses an EventMachine server to accept incoming connections, and then delegates the request to loadable Ruby handlers. BERTREM is derived from [Ernie](http://github.com/mojombo/ernie), by Tom Preston-Warner.
|
7
|
+
|
8
|
+
See the full BERT-RPC specification at [bert-rpc.org](http://bert-rpc.org).
|
9
|
+
|
10
|
+
BERTREM currently supports the following BERT-RPC features:
|
11
|
+
|
12
|
+
* `call` requests
|
13
|
+
* `cast` requests
|
14
|
+
|
15
|
+
|
16
|
+
Installation
|
17
|
+
------------
|
18
|
+
|
19
|
+
$ gem install bertrem -s http://gemcutter.org
|
20
|
+
|
21
|
+
|
22
|
+
Example Handler
|
23
|
+
---------------
|
24
|
+
|
25
|
+
A simple Ruby module for use in a BERTREM server:
|
26
|
+
|
27
|
+
require 'bertrem'
|
28
|
+
|
29
|
+
module Calc
|
30
|
+
def add(a, b)
|
31
|
+
a + b
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
|
36
|
+
Example Server
|
37
|
+
--------------
|
38
|
+
|
39
|
+
A simple BERTREM server using the Calc module defined above:
|
40
|
+
|
41
|
+
require 'eventmachine'
|
42
|
+
require 'bertrem'
|
43
|
+
|
44
|
+
EM.run {
|
45
|
+
BERTREM::Server.expose(:calc, Calc)
|
46
|
+
svc = BERTREM::Server.start('localhost', 9999)
|
47
|
+
}
|
48
|
+
|
49
|
+
|
50
|
+
Logging
|
51
|
+
-------
|
52
|
+
|
53
|
+
You can have logging sent to a file by adding these lines to your handler:
|
54
|
+
|
55
|
+
logfile('/var/log/bertrem.log')
|
56
|
+
loglevel(Logger::INFO)
|
57
|
+
|
58
|
+
This will log startup info, requests, and error messages to the log. Choosing
|
59
|
+
Logger::DEBUG will include the response (be careful, doing this can generate
|
60
|
+
very large log files).
|
61
|
+
|
62
|
+
|
63
|
+
Using the BERTRPC gem to make calls to BERTREM
|
64
|
+
---------------------------------------------__
|
65
|
+
|
66
|
+
The BERTREM client supports persistent connections, so you can send multiple requests over the same service connection and responses will return in the order the requests were sent:
|
67
|
+
|
68
|
+
require 'eventmachine'
|
69
|
+
require 'bertrem'
|
70
|
+
|
71
|
+
EM.run {
|
72
|
+
client = BERTREM::Client.service('localhost', 9999, true)
|
73
|
+
rpc = client.call.calc.add(6, 2)
|
74
|
+
rpc.callback { |res|
|
75
|
+
puts "Got response! -> #{res}"
|
76
|
+
}
|
77
|
+
|
78
|
+
rpc = client.call.calc.add(2, 2)
|
79
|
+
rpc.callback { |res|
|
80
|
+
puts "Got response! -> #{res}"
|
81
|
+
}
|
82
|
+
}
|
83
|
+
# Got response! -> 8
|
84
|
+
# Got response! -> 4
|
85
|
+
|
86
|
+
Alternatively, you can make BERT-RPC calls from Ruby with the [BERTRPC gem](http://github.com/mojombo/bertrpc):
|
87
|
+
|
88
|
+
require 'bertrpc'
|
89
|
+
|
90
|
+
svc = BERTRPC::Service.new('localhost', 8000)
|
91
|
+
svc.call.calc.add(1, 2)
|
92
|
+
# => 3
|
93
|
+
|
94
|
+
|
95
|
+
Contribute
|
96
|
+
----------
|
97
|
+
|
98
|
+
If you'd like to hack on BERTREM, start by forking my repo on GitHub:
|
99
|
+
|
100
|
+
http://github.com/b/bertrem
|
101
|
+
|
102
|
+
To get all of the dependencies, install the gem first
|
103
|
+
|
104
|
+
The best way to get your changes merged back into core is as follows:
|
105
|
+
|
106
|
+
1. Clone down your fork
|
107
|
+
1. Create a topic branch to contain your change
|
108
|
+
1. Hack away
|
109
|
+
1. Add tests and make sure everything still passes by running `rake`
|
110
|
+
1. If you are adding new functionality, document it in the README.md
|
111
|
+
1. Do not change the version number, I will do that on my end
|
112
|
+
1. If necessary, rebase your commits into logical chunks, without errors
|
113
|
+
1. Push the branch up to GitHub
|
114
|
+
1. Send me (b) a pull request for your branch
|
115
|
+
|
116
|
+
|
117
|
+
Copyright
|
118
|
+
---------
|
119
|
+
|
120
|
+
Copyright (c) 2009 Benjamin Black. See LICENSE for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "bertrem"
|
8
|
+
gem.summary = %Q{BERTREM is a Ruby EventMachine BERT-RPC client and server library.}
|
9
|
+
gem.email = "b@b3k.us"
|
10
|
+
gem.homepage = "http://github.com/b/bertrem"
|
11
|
+
gem.authors = ["Benjamin Black"]
|
12
|
+
gem.add_dependency('bertrpc', '>= 1.1.2', '< 2.0.0')
|
13
|
+
gem.add_dependency('eventmachine')
|
14
|
+
# gem is a Gem::Specification...
|
15
|
+
# see http://www.rubygems.org/read/chapter/20 for additional settings
|
16
|
+
end
|
17
|
+
|
18
|
+
rescue LoadError
|
19
|
+
puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
|
20
|
+
end
|
21
|
+
|
22
|
+
task :console do
|
23
|
+
exec('irb -Ilib -rbertrpc')
|
24
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.0.4
|
data/bertem.gemspec
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{bertem}
|
8
|
+
s.version = "0.0.4"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Benjamin Black"]
|
12
|
+
s.date = %q{2009-12-30}
|
13
|
+
s.email = %q{b@b3k.us}
|
14
|
+
s.extra_rdoc_files = [
|
15
|
+
"LICENSE",
|
16
|
+
"README.md"
|
17
|
+
]
|
18
|
+
s.files = [
|
19
|
+
"LICENSE",
|
20
|
+
"README.md",
|
21
|
+
"Rakefile",
|
22
|
+
"VERSION",
|
23
|
+
"bertem.gemspec",
|
24
|
+
"lib/bertem.rb",
|
25
|
+
"lib/bertem/action.rb",
|
26
|
+
"lib/bertem/client.rb",
|
27
|
+
"lib/bertem/mod.rb",
|
28
|
+
"lib/bertem/server.rb"
|
29
|
+
]
|
30
|
+
s.homepage = %q{http://github.com/b/bertem}
|
31
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
32
|
+
s.require_paths = ["lib"]
|
33
|
+
s.rubygems_version = %q{1.3.5}
|
34
|
+
s.summary = %q{BERTEM is a Ruby EventMachine BERT-RPC client and server library.}
|
35
|
+
|
36
|
+
if s.respond_to? :specification_version then
|
37
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
38
|
+
s.specification_version = 3
|
39
|
+
|
40
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
41
|
+
s.add_runtime_dependency(%q<bertrpc>, [">= 1.1.2", "< 2.0.0"])
|
42
|
+
s.add_runtime_dependency(%q<eventmachine>, [">= 0"])
|
43
|
+
else
|
44
|
+
s.add_dependency(%q<bertrpc>, [">= 1.1.2", "< 2.0.0"])
|
45
|
+
s.add_dependency(%q<eventmachine>, [">= 0"])
|
46
|
+
end
|
47
|
+
else
|
48
|
+
s.add_dependency(%q<bertrpc>, [">= 1.1.2", "< 2.0.0"])
|
49
|
+
s.add_dependency(%q<eventmachine>, [">= 0"])
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
data/lib/bertrem.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'logger'
|
2
|
+
require 'bertrpc'
|
3
|
+
require 'eventmachine'
|
4
|
+
|
5
|
+
require 'bertrem/action'
|
6
|
+
require 'bertrem/mod'
|
7
|
+
require 'bertrem/client'
|
8
|
+
require 'bertrem/server'
|
9
|
+
|
10
|
+
module BERTREM
|
11
|
+
def self.version
|
12
|
+
File.read(File.join(File.dirname(__FILE__), *%w[.. VERSION])).chomp
|
13
|
+
rescue
|
14
|
+
'unknown'
|
15
|
+
end
|
16
|
+
|
17
|
+
VERSION = self.version
|
18
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'eventmachine'
|
2
|
+
require 'bertrpc'
|
3
|
+
|
4
|
+
module BERTRPC
|
5
|
+
class Action
|
6
|
+
|
7
|
+
undef_method :execute
|
8
|
+
undef_method :write
|
9
|
+
undef_method :transaction
|
10
|
+
undef_method :connect_to
|
11
|
+
|
12
|
+
def execute
|
13
|
+
transaction(encode_ruby_request(t[@req.kind, @mod, @fun, @args]))
|
14
|
+
@svc.requests.unshift(EM::DefaultDeferrable.new).first
|
15
|
+
end
|
16
|
+
|
17
|
+
def write(bert)
|
18
|
+
@svc.send_data([bert.length].pack("N"))
|
19
|
+
@svc.send_data(bert)
|
20
|
+
end
|
21
|
+
|
22
|
+
def transaction(bert_request)
|
23
|
+
if @req.options
|
24
|
+
if @req.options[:cache] && @req.options[:cache][0] == :validation
|
25
|
+
token = @req.options[:cache][1]
|
26
|
+
info_bert = encode_ruby_request([:info, :cache, [:validation, token]])
|
27
|
+
write(info_bert)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
write(bert_request)
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
require 'bertrpc'
|
2
|
+
require 'logger'
|
3
|
+
require 'eventmachine'
|
4
|
+
|
5
|
+
module BERTREM
|
6
|
+
# NOTE: ernie (and all other BERTRPC servers?) closes connections after
|
7
|
+
# responding, so we can't send multiple requests per connection.
|
8
|
+
# Hence, the default for persistent is false. If you are dealing
|
9
|
+
# with a more sophisticated server that supports more than one
|
10
|
+
# request per connection, call BERTREM.service with
|
11
|
+
# persistent = true and it should Just Work.
|
12
|
+
|
13
|
+
class Client < EventMachine::Connection
|
14
|
+
include BERTRPC::Encodes
|
15
|
+
|
16
|
+
attr_accessor :requests
|
17
|
+
|
18
|
+
class Request
|
19
|
+
attr_accessor :kind, :options
|
20
|
+
|
21
|
+
def initialize(svc, kind, options)
|
22
|
+
@svc = svc
|
23
|
+
@kind = kind
|
24
|
+
@options = options
|
25
|
+
end
|
26
|
+
|
27
|
+
def method_missing(cmd, *args)
|
28
|
+
BERTRPC::Mod.new(@svc, self, cmd)
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
class << self
|
34
|
+
attr_accessor :persistent
|
35
|
+
end
|
36
|
+
|
37
|
+
self.persistent = false
|
38
|
+
|
39
|
+
def self.service(host, port, persistent = false, timeout = nil)
|
40
|
+
self.persistent = persistent
|
41
|
+
c = EM.connect(host, port, self)
|
42
|
+
c.pending_connect_timeout = timeout if timeout
|
43
|
+
c
|
44
|
+
end
|
45
|
+
|
46
|
+
def post_init
|
47
|
+
@requests = []
|
48
|
+
end
|
49
|
+
|
50
|
+
def unbind
|
51
|
+
super
|
52
|
+
(@requests || []).each {|r| r.fail}
|
53
|
+
end
|
54
|
+
|
55
|
+
def persistent
|
56
|
+
Client.persistent
|
57
|
+
end
|
58
|
+
|
59
|
+
def receive_data(bert_response)
|
60
|
+
# This needs to be much more intelligent (retain a buffer, append new response data
|
61
|
+
# to the buffer, remember the length of the msg it is working with if it is incomplete,
|
62
|
+
# etc.)
|
63
|
+
while bert_response.length > 4 do
|
64
|
+
begin
|
65
|
+
raise BERTRPC::ProtocolError.new(BERTRPC::ProtocolError::NO_HEADER) unless bert_response.length > 4
|
66
|
+
len = bert_response.slice!(0..3).unpack('N').first # just here to strip the length header
|
67
|
+
raise BERTRPC::ProtocolError.new(BERTRPC::ProtocolError::NO_DATA) unless bert_response.length > 0
|
68
|
+
rescue Exception => e
|
69
|
+
log "Bad BERT message: #{e.message}\n#{e.backtrace.inspect}\n"
|
70
|
+
end
|
71
|
+
|
72
|
+
bert = bert_response.slice!(0..(len - 1))
|
73
|
+
@requests.pop.succeed(decode_bert_response(bert))
|
74
|
+
unless persistent
|
75
|
+
close_connection
|
76
|
+
break
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def call(options = nil)
|
82
|
+
verify_options(options)
|
83
|
+
Request.new(self, :call, options)
|
84
|
+
end
|
85
|
+
|
86
|
+
def cast(options = nil)
|
87
|
+
verify_options(options)
|
88
|
+
Request.new(self, :cast, options)
|
89
|
+
end
|
90
|
+
|
91
|
+
def verify_options(options)
|
92
|
+
if options
|
93
|
+
if cache = options[:cache]
|
94
|
+
unless cache[0] == :validation && cache[1].is_a?(String)
|
95
|
+
raise BERTRPC::InvalidOption.new("Valid :cache args are [:validation, String]")
|
96
|
+
end
|
97
|
+
else
|
98
|
+
raise BERTRPC::InvalidOption.new("Valid options are :cache")
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
end
|
104
|
+
|
105
|
+
end
|
data/lib/bertrem/mod.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
module BERTREM
|
2
|
+
class Mod
|
3
|
+
|
4
|
+
attr_accessor :name, :funs
|
5
|
+
|
6
|
+
def initialize(name)
|
7
|
+
self.name = name
|
8
|
+
self.funs = {}
|
9
|
+
end
|
10
|
+
|
11
|
+
def fun(name, block)
|
12
|
+
raise TypeError, "block required" if block.nil?
|
13
|
+
self.funs[name] = block
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
@@ -0,0 +1,164 @@
|
|
1
|
+
require 'bert'
|
2
|
+
require 'logger'
|
3
|
+
require 'eventmachine'
|
4
|
+
|
5
|
+
module BERTREM
|
6
|
+
class Server < EventMachine::Connection
|
7
|
+
include BERTRPC::Encodes
|
8
|
+
|
9
|
+
# This class derived from Ernie/ernie.rb
|
10
|
+
|
11
|
+
class << self
|
12
|
+
attr_accessor :mods, :current_mod, :log
|
13
|
+
end
|
14
|
+
|
15
|
+
self.mods = {}
|
16
|
+
self.current_mod = nil
|
17
|
+
self.log = Logger.new(STDOUT)
|
18
|
+
self.log.level = Logger::INFO
|
19
|
+
|
20
|
+
def self.start(host, port)
|
21
|
+
EM.start_server(host, port, self)
|
22
|
+
end
|
23
|
+
|
24
|
+
# Record a module.
|
25
|
+
# +name+ is the module Symbol
|
26
|
+
# +block+ is the Block containing function definitions
|
27
|
+
#
|
28
|
+
# Returns nothing
|
29
|
+
def self.mod(name, block)
|
30
|
+
m = Mod.new(name)
|
31
|
+
self.current_mod = m
|
32
|
+
self.mods[name] = m
|
33
|
+
block.call
|
34
|
+
end
|
35
|
+
|
36
|
+
# Record a function.
|
37
|
+
# +name+ is the function Symbol
|
38
|
+
# +block+ is the Block to associate
|
39
|
+
#
|
40
|
+
# Returns nothing
|
41
|
+
def self.fun(name, block)
|
42
|
+
self.current_mod.fun(name, block)
|
43
|
+
end
|
44
|
+
|
45
|
+
# Expose all public methods in a Ruby module:
|
46
|
+
# +name+ is the ernie module Symbol
|
47
|
+
# +mixin+ is the ruby module whose public methods are exposed
|
48
|
+
#
|
49
|
+
# Returns nothing
|
50
|
+
def self.expose(name, mixin)
|
51
|
+
context = Object.new
|
52
|
+
context.extend mixin
|
53
|
+
self.mod(name, lambda {
|
54
|
+
mixin.public_instance_methods.each do |meth|
|
55
|
+
self.fun(meth.to_sym, context.method(meth))
|
56
|
+
end
|
57
|
+
})
|
58
|
+
context
|
59
|
+
end
|
60
|
+
|
61
|
+
# Set the logfile to given path.
|
62
|
+
# +file+ is the String path to the logfile
|
63
|
+
#
|
64
|
+
# Returns nothing
|
65
|
+
def self.logfile(file)
|
66
|
+
self.log = Logger.new(file)
|
67
|
+
end
|
68
|
+
|
69
|
+
# Set the log level.
|
70
|
+
# +level+ is the Logger level (Logger::WARN, etc)
|
71
|
+
#
|
72
|
+
# Returns nothing
|
73
|
+
def self.loglevel(level)
|
74
|
+
self.log.level = level
|
75
|
+
end
|
76
|
+
|
77
|
+
# Dispatch the request to the proper mod:fun.
|
78
|
+
# +mod+ is the module Symbol
|
79
|
+
# +fun+ is the function Symbol
|
80
|
+
# +args+ is the Array of arguments
|
81
|
+
#
|
82
|
+
# Returns the Ruby object response
|
83
|
+
def self.dispatch(mod, fun, args)
|
84
|
+
mods[mod] || raise(ServerError.new("No such module '#{mod}'"))
|
85
|
+
mods[mod].funs[fun] || raise(ServerError.new("No such function '#{mod}:#{fun}'"))
|
86
|
+
mods[mod].funs[fun].call(*args)
|
87
|
+
end
|
88
|
+
|
89
|
+
# Write the given Ruby object to the wire as a BERP.
|
90
|
+
# +output+ is the IO on which to write
|
91
|
+
# +ruby+ is the Ruby object to encode
|
92
|
+
#
|
93
|
+
# Returns nothing
|
94
|
+
def write_berp(ruby)
|
95
|
+
data = BERT.encode(ruby)
|
96
|
+
send_data([data.length].pack("N"))
|
97
|
+
send_data(data)
|
98
|
+
end
|
99
|
+
|
100
|
+
def post_init
|
101
|
+
Server.log.info("(#{Process.pid}) Starting")
|
102
|
+
Server.log.debug(Server.mods.inspect)
|
103
|
+
end
|
104
|
+
|
105
|
+
# Receive data on the connection.
|
106
|
+
#
|
107
|
+
def receive_data(data)
|
108
|
+
# This needs to be much more intelligent (retain a buffer, append new request data
|
109
|
+
# to the buffer, remember the length of the msg it is working with if it is incomplete,
|
110
|
+
# etc.)
|
111
|
+
while data.length > 4 do
|
112
|
+
raw = data.slice!(0..3)
|
113
|
+
puts "Could not find BERP length header. Weird, huh?" unless raw
|
114
|
+
packet_size = raw.unpack('N').first
|
115
|
+
puts "Could not understand BERP packet length. What gives?" unless packet_size
|
116
|
+
bert = data.slice!(0..(packet_size - 1))
|
117
|
+
iruby = BERT.decode(bert)
|
118
|
+
|
119
|
+
unless iruby
|
120
|
+
Server.log.info("(#{Process.pid}) No Ruby in this here packet. On to the next one...")
|
121
|
+
next
|
122
|
+
end
|
123
|
+
|
124
|
+
if iruby.size == 4 && iruby[0] == :call
|
125
|
+
mod, fun, args = iruby[1..3]
|
126
|
+
Server.log.info("-> " + iruby.inspect)
|
127
|
+
begin
|
128
|
+
res = Server.dispatch(mod, fun, args)
|
129
|
+
oruby = t[:reply, res]
|
130
|
+
Server.log.debug("<- " + oruby.inspect)
|
131
|
+
write_berp(oruby)
|
132
|
+
rescue ServerError => e
|
133
|
+
oruby = t[:error, t[:server, 0, e.class.to_s, e.message, e.backtrace]]
|
134
|
+
Server.log.error("<- " + oruby.inspect)
|
135
|
+
Server.log.error(e.backtrace.join("\n"))
|
136
|
+
write_berp(oruby)
|
137
|
+
rescue Object => e
|
138
|
+
oruby = t[:error, t[:user, 0, e.class.to_s, e.message, e.backtrace]]
|
139
|
+
Server.log.error("<- " + oruby.inspect)
|
140
|
+
Server.log.error(e.backtrace.join("\n"))
|
141
|
+
write_berp(oruby)
|
142
|
+
end
|
143
|
+
elsif iruby.size == 4 && iruby[0] == :cast
|
144
|
+
mod, fun, args = iruby[1..3]
|
145
|
+
Server.log.info("-> " + [:cast, mod, fun, args].inspect)
|
146
|
+
begin
|
147
|
+
Server.dispatch(mod, fun, args)
|
148
|
+
rescue Object => e
|
149
|
+
# ignore
|
150
|
+
end
|
151
|
+
write_berp(t[:noreply])
|
152
|
+
else
|
153
|
+
Server.log.error("-> " + iruby.inspect)
|
154
|
+
oruby = t[:error, t[:server, 0, "Invalid request: #{iruby.inspect}"]]
|
155
|
+
Server.log.error("<- " + oruby.inspect)
|
156
|
+
write_berp(oruby)
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
end
|
163
|
+
|
164
|
+
class BERTREM::ServerError < StandardError; end
|
metadata
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: bertrem
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.4
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Benjamin Black
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2010-01-01 00:00:00 -08:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: bertrpc
|
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.2
|
24
|
+
- - <
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 2.0.0
|
27
|
+
version:
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: eventmachine
|
30
|
+
type: :runtime
|
31
|
+
version_requirement:
|
32
|
+
version_requirements: !ruby/object:Gem::Requirement
|
33
|
+
requirements:
|
34
|
+
- - ">="
|
35
|
+
- !ruby/object:Gem::Version
|
36
|
+
version: "0"
|
37
|
+
version:
|
38
|
+
description:
|
39
|
+
email: b@b3k.us
|
40
|
+
executables: []
|
41
|
+
|
42
|
+
extensions: []
|
43
|
+
|
44
|
+
extra_rdoc_files:
|
45
|
+
- LICENSE
|
46
|
+
- README.md
|
47
|
+
files:
|
48
|
+
- LICENSE
|
49
|
+
- README.md
|
50
|
+
- Rakefile
|
51
|
+
- VERSION
|
52
|
+
- bertem.gemspec
|
53
|
+
- lib/bertrem.rb
|
54
|
+
- lib/bertrem/action.rb
|
55
|
+
- lib/bertrem/client.rb
|
56
|
+
- lib/bertrem/mod.rb
|
57
|
+
- lib/bertrem/server.rb
|
58
|
+
has_rdoc: true
|
59
|
+
homepage: http://github.com/b/bertrem
|
60
|
+
licenses: []
|
61
|
+
|
62
|
+
post_install_message:
|
63
|
+
rdoc_options:
|
64
|
+
- --charset=UTF-8
|
65
|
+
require_paths:
|
66
|
+
- lib
|
67
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
68
|
+
requirements:
|
69
|
+
- - ">="
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
version: "0"
|
72
|
+
version:
|
73
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
74
|
+
requirements:
|
75
|
+
- - ">="
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: "0"
|
78
|
+
version:
|
79
|
+
requirements: []
|
80
|
+
|
81
|
+
rubyforge_project:
|
82
|
+
rubygems_version: 1.3.5
|
83
|
+
signing_key:
|
84
|
+
specification_version: 3
|
85
|
+
summary: BERTREM is a Ruby EventMachine BERT-RPC client and server library.
|
86
|
+
test_files: []
|
87
|
+
|