bertrem 0.0.4 → 0.0.6

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