bertrem 0.0.4 → 0.0.6

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/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.4
1
+ 0.0.6
@@ -4,12 +4,12 @@
4
4
  # -*- encoding: utf-8 -*-
5
5
 
6
6
  Gem::Specification.new do |s|
7
- s.name = %q{bertem}
8
- s.version = "0.0.4"
7
+ s.name = %q{bertrem}
8
+ s.version = "0.0.6"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Benjamin Black"]
12
- s.date = %q{2009-12-30}
12
+ s.date = %q{2010-01-02}
13
13
  s.email = %q{b@b3k.us}
14
14
  s.extra_rdoc_files = [
15
15
  "LICENSE",
@@ -20,18 +20,18 @@ Gem::Specification.new do |s|
20
20
  "README.md",
21
21
  "Rakefile",
22
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"
23
+ "bertrem.gemspec",
24
+ "lib/bertrem.rb",
25
+ "lib/bertrem/action.rb",
26
+ "lib/bertrem/client.rb",
27
+ "lib/bertrem/mod.rb",
28
+ "lib/bertrem/server.rb"
29
29
  ]
30
- s.homepage = %q{http://github.com/b/bertem}
30
+ s.homepage = %q{http://github.com/b/bertrem}
31
31
  s.rdoc_options = ["--charset=UTF-8"]
32
32
  s.require_paths = ["lib"]
33
33
  s.rubygems_version = %q{1.3.5}
34
- s.summary = %q{BERTEM is a Ruby EventMachine BERT-RPC client and server library.}
34
+ s.summary = %q{BERTREM is a Ruby EventMachine BERT-RPC client and server library.}
35
35
 
36
36
  if s.respond_to? :specification_version then
37
37
  current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
@@ -4,10 +4,9 @@ require 'bertrpc'
4
4
  module BERTRPC
5
5
  class Action
6
6
 
7
- undef_method :execute
8
- undef_method :write
9
- undef_method :transaction
10
- undef_method :connect_to
7
+ [:execute, :write, :transaction, :connect_to].each do |m|
8
+ remove_method m if method_defined?(m)
9
+ end
11
10
 
12
11
  def execute
13
12
  transaction(encode_ruby_request(t[@req.kind, @mod, @fun, @args]))
@@ -3,13 +3,12 @@ require 'logger'
3
3
  require 'eventmachine'
4
4
 
5
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
-
6
+ # NOTE: ernie closes connections after responding, so we can't send
7
+ # multiple requests per connection. Hence, the default for
8
+ # persistent is false. If you are working with a server that
9
+ # supports more than one request per connection, like
10
+ # BERTREM::Server, call BERTREM.service with persistent = true
11
+ # and it will Just Work.
13
12
  class Client < EventMachine::Connection
14
13
  include BERTRPC::Encodes
15
14
 
@@ -33,7 +32,7 @@ module BERTREM
33
32
  class << self
34
33
  attr_accessor :persistent
35
34
  end
36
-
35
+
37
36
  self.persistent = false
38
37
 
39
38
  def self.service(host, port, persistent = false, timeout = nil)
@@ -44,38 +43,51 @@ module BERTREM
44
43
  end
45
44
 
46
45
  def post_init
46
+ @receive_buf = ""; @receive_len = 0; @more = false
47
47
  @requests = []
48
48
  end
49
49
 
50
50
  def unbind
51
- super
52
- (@requests || []).each {|r| r.fail}
51
+ super
52
+ @receive_buf = ""; @receive_len = 0; @more = false
53
+ (@requests || []).each {|r| r.fail}
54
+ raise BERTREM::ConnectionError.new("Connection to server lost!") if error?
53
55
  end
54
-
56
+
55
57
  def persistent
56
58
  Client.persistent
57
59
  end
58
60
 
59
61
  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"
62
+ @receive_buf << bert_response
63
+
64
+ while @receive_buf.length > 0
65
+ unless @more
66
+ begin
67
+ if @receive_buf.length > 4
68
+ @receive_len = @receive_buf.slice!(0..3).unpack('N').first if @receive_len == 0
69
+ raise BERTRPC::ProtocolError.new(BERTRPC::ProtocolError::NO_DATA) unless @receive_buf.length > 0
70
+ else
71
+ raise BERTRPC::ProtocolError.new(BERTRPC::ProtocolError::NO_HEADER)
72
+ end
73
+ rescue Exception => e
74
+ log "Bad BERT message: #{e.message}"
75
+ return
76
+ end
70
77
  end
71
-
72
- bert = bert_response.slice!(0..(len - 1))
73
- @requests.pop.succeed(decode_bert_response(bert))
74
- unless persistent
75
- close_connection
78
+
79
+ if @receive_buf.length >= @receive_len
80
+ bert = @receive_buf.slice!(0..(@receive_len - 1))
81
+ @receive_len = 0; @more = false
82
+ @requests.pop.succeed(decode_bert_response(bert))
83
+ break unless persistent
84
+ else
85
+ @more = true
76
86
  break
77
87
  end
78
88
  end
89
+
90
+ close_connection unless (persistent || @more)
79
91
  end
80
92
 
81
93
  def call(options = nil)
@@ -103,3 +115,5 @@ module BERTREM
103
115
  end
104
116
 
105
117
  end
118
+
119
+ class BERTREM::ConnectionError < StandardError ; end
@@ -5,22 +5,22 @@ require 'eventmachine'
5
5
  module BERTREM
6
6
  class Server < EventMachine::Connection
7
7
  include BERTRPC::Encodes
8
-
8
+
9
9
  # This class derived from Ernie/ernie.rb
10
-
10
+
11
11
  class << self
12
12
  attr_accessor :mods, :current_mod, :log
13
13
  end
14
-
14
+
15
15
  self.mods = {}
16
16
  self.current_mod = nil
17
17
  self.log = Logger.new(STDOUT)
18
18
  self.log.level = Logger::INFO
19
-
19
+
20
20
  def self.start(host, port)
21
21
  EM.start_server(host, port, self)
22
22
  end
23
-
23
+
24
24
  # Record a module.
25
25
  # +name+ is the module Symbol
26
26
  # +block+ is the Block containing function definitions
@@ -73,7 +73,7 @@ module BERTREM
73
73
  def self.loglevel(level)
74
74
  self.log.level = level
75
75
  end
76
-
76
+
77
77
  # Dispatch the request to the proper mod:fun.
78
78
  # +mod+ is the module Symbol
79
79
  # +fun+ is the function Symbol
@@ -96,69 +96,85 @@ module BERTREM
96
96
  send_data([data.length].pack("N"))
97
97
  send_data(data)
98
98
  end
99
-
99
+
100
100
  def post_init
101
+ @receive_buf = ""; @receive_len = 0; @more = false
101
102
  Server.log.info("(#{Process.pid}) Starting")
102
- Server.log.debug(Server.mods.inspect)
103
+ Server.log.debug(Server.mods.inspect)
103
104
  end
104
-
105
+
105
106
  # Receive data on the connection.
106
107
  #
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
108
+ def receive_data(bert_request)
109
+ @receive_buf << bert_request
123
110
 
124
- if iruby.size == 4 && iruby[0] == :call
125
- mod, fun, args = iruby[1..3]
126
- Server.log.info("-> " + iruby.inspect)
111
+ while @receive_buf.length > 0 do
112
+ unless @more
127
113
  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]]
114
+ if @receive_buf.length > 4
115
+ @receive_len = @receive_buf.slice!(0..3).unpack('N').first if @receive_len == 0
116
+ raise BERTRPC::ProtocolError.new(BERTRPC::ProtocolError::NO_DATA) unless @receive_buf.length > 0
117
+ else
118
+ raise BERTRPC::ProtocolError.new(BERTRPC::ProtocolError::NO_HEADER)
119
+ end
120
+ rescue Exception => e
121
+ log "Bad BERT message: #{e.message}"
122
+ return
123
+ end
124
+ end
125
+
126
+ if @receive_buf.length >= @receive_len
127
+ bert = @receive_buf.slice!(0..(@receive_len - 1))
128
+ @receive_len = 0; @more = false
129
+ iruby = BERT.decode(bert)
130
+
131
+ unless iruby
132
+ Server.log.info("(#{Process.pid}) No Ruby in this here packet. On to the next one...")
133
+ next
134
+ end
135
+
136
+ if iruby.size == 4 && iruby[0] == :call
137
+ mod, fun, args = iruby[1..3]
138
+ Server.log.info("-> " + iruby.inspect)
139
+ begin
140
+ res = Server.dispatch(mod, fun, args)
141
+ oruby = t[:reply, res]
142
+ Server.log.debug("<- " + oruby.inspect)
143
+ write_berp(oruby)
144
+ rescue ServerError => e
145
+ oruby = t[:error, t[:server, 0, e.class.to_s, e.message, e.backtrace]]
146
+ Server.log.error("<- " + oruby.inspect)
147
+ Server.log.error(e.backtrace.join("\n"))
148
+ write_berp(oruby)
149
+ rescue Object => e
150
+ oruby = t[:error, t[:user, 0, e.class.to_s, e.message, e.backtrace]]
151
+ Server.log.error("<- " + oruby.inspect)
152
+ Server.log.error(e.backtrace.join("\n"))
153
+ write_berp(oruby)
154
+ end
155
+ elsif iruby.size == 4 && iruby[0] == :cast
156
+ mod, fun, args = iruby[1..3]
157
+ Server.log.info("-> " + [:cast, mod, fun, args].inspect)
158
+ begin
159
+ Server.dispatch(mod, fun, args)
160
+ rescue Object => e
161
+ # ignore
162
+ end
163
+ write_berp(t[:noreply])
164
+ else
165
+ Server.log.error("-> " + iruby.inspect)
166
+ oruby = t[:error, t[:server, 0, "Invalid request: #{iruby.inspect}"]]
139
167
  Server.log.error("<- " + oruby.inspect)
140
- Server.log.error(e.backtrace.join("\n"))
141
168
  write_berp(oruby)
142
169
  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
170
  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)
171
+ @more = true
172
+ break
157
173
  end
158
174
  end
159
175
  end
160
176
  end
161
-
177
+
162
178
  end
163
179
 
164
180
  class BERTREM::ServerError < StandardError; end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bertrem
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.0.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Benjamin Black
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2010-01-01 00:00:00 -08:00
12
+ date: 2010-01-02 00:00:00 -08:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -49,7 +49,7 @@ files:
49
49
  - README.md
50
50
  - Rakefile
51
51
  - VERSION
52
- - bertem.gemspec
52
+ - bertrem.gemspec
53
53
  - lib/bertrem.rb
54
54
  - lib/bertrem/action.rb
55
55
  - lib/bertrem/client.rb