bertrem 0.0.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/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
|
+
|