em-rserve 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile CHANGED
@@ -1,4 +1,7 @@
1
1
  source "http://rubygems.org"
2
2
 
3
- # Specify your gem's dependencies in em-rserve.gemspec
4
- gemspec
3
+ gem "eventmachine"
4
+
5
+ group :development, :test do
6
+ gem "rspec"
7
+ end
data/README CHANGED
@@ -15,7 +15,6 @@ So far it can:
15
15
  - handle pools of connections with ruby fibers
16
16
 
17
17
  Limitations:
18
- - large QAP1 messages (>8MB) are not supported, this limitation means that you cannot transfer large object directly over RServe protocol
19
18
  - no support for the connections with a password. somehow, password without encryption defeats the purpose. hence, if you need a password, you should setup an SSH proxy instead
20
19
 
21
20
  Links:
data/TODO CHANGED
@@ -4,7 +4,7 @@
4
4
  - Table
5
5
  * RESP_ERR as a flag and not an OR-ed value
6
6
  -> will need to modify Header#error? and Header#error
7
- * support for long (>8M) messages
7
+ * factorize headers parsing/dumping for SEXP and QAP1 parameters
8
8
  * login command
9
9
  support crypt and store salt from connection setup
10
10
  * better attach method
@@ -21,6 +21,7 @@ module EM::Rserve
21
21
  @connections = []
22
22
  @size = size
23
23
  @connection_class = klass
24
+ fill size
24
25
  end
25
26
 
26
27
  def empty?
@@ -11,7 +11,7 @@ module EM::Rserve
11
11
  end
12
12
 
13
13
  def message_length
14
- length #TODO: use length2
14
+ length | length2 << 32
15
15
  end
16
16
 
17
17
  def body?
@@ -37,9 +37,6 @@ module EM::Rserve
37
37
  def error
38
38
  ((command & ~Constants::RESP_ERR) >> 24) & 0xff
39
39
  end
40
-
41
- # -> self.for_message
42
- # -> prepare_message
43
40
  end
44
41
  end
45
42
  end
@@ -8,13 +8,21 @@ module EM::Rserve
8
8
  include Constants
9
9
  include R
10
10
 
11
+ LARGE_SIZE_TRESHOLD = 0xfffff0
12
+
11
13
  def parameter_head(type, len)
12
- #TODO: support long parameter, type: 0xbf + DT_LARGE if len overflows
13
- (type & 0x000000ff) | ((len << 8) & 0xffffff00)
14
+ if len > LARGE_SIZE_TRESHOLD
15
+ head = (type & 0x000000bf) | ((len << 8) & 0xffffff00) | DT_LARGE
16
+ extra_len_bits = (len & ~0xffffff) >> 24
17
+ [head, extra_len_bits].pack('VV')
18
+ else
19
+ head = (type & 0x000000bf) | ((len << 8) & 0xffffff00)
20
+ [head].pack('V')
21
+ end
14
22
  end
15
23
 
16
24
  def pack_parameter(type, len, val, rule)
17
- [parameter_head(type, len), val].flatten.pack('V'+rule)
25
+ [parameter_head(type, len), val].flatten.pack('a*'+rule)
18
26
  end
19
27
 
20
28
  def encode_parameter(param, type=nil)
@@ -76,9 +84,9 @@ module EM::Rserve
76
84
  end
77
85
 
78
86
  def head_parameter(head)
79
- type = head & 0x000000bf
87
+ type = head & 0x000000bf
80
88
  large = (head & DT_LARGE) > 0
81
- len = (head & 0xffffff00) >> 8
89
+ len = (head & 0xffffff00) >> 8
82
90
  [type, len, large]
83
91
  end
84
92
 
@@ -112,7 +120,10 @@ module EM::Rserve
112
120
  until buffer.empty? do
113
121
  head, buffer = buffer.unpack('Va*')
114
122
  type, len, large = head_parameter(head)
115
- raise NotImplementedError, "too long QAP1 message" if large
123
+ if large
124
+ long_len, buffer = buffer.unpack('Va*')
125
+ len = long_len << 24 | len
126
+ end
116
127
  if buffer.size < len
117
128
  raise RuntimeError, "cannot decode #{buffer} (not enough bytes)"
118
129
  end
@@ -57,6 +57,8 @@ module EM::Rserve
57
57
  end
58
58
  end
59
59
 
60
+ LARGE_SIZE_TRESHOLD = 0xfffff0 #recommandation
61
+
60
62
  def dump_sexp
61
63
  body = dumped_value_with_attribute
62
64
  children_data = children.map do |n|
@@ -64,8 +66,9 @@ module EM::Rserve
64
66
  end.join('')
65
67
  size = body.size + children_data.size
66
68
  flags = {:large => false, :attr => attribute && true}
69
+ flags[:large] = true if size > LARGE_SIZE_TRESHOLD
67
70
  head = self.class.parameter_head(self.class.code, flags, size)
68
- [head, body + children_data].pack('Va*')
71
+ [head, body + children_data].join('')
69
72
  end
70
73
 
71
74
  def dumped_value_with_attribute
@@ -84,10 +87,16 @@ module EM::Rserve
84
87
  head_bits = type & 0x3f #high bits are for flags
85
88
  len_bits = (len & 0xffffff) << 8
86
89
  flags_bits = 0
87
- flags_bits |= 0x40 if flags[:large]
88
90
  flags_bits |= 0x80 if flags[:attr]
89
- ret = head_bits | len_bits | flags_bits
90
- ret
91
+ if flags[:large]
92
+ flags_bits |= 0x40
93
+ head = head_bits | len_bits | flags_bits
94
+ extra_len_bits = (len & ~0xffffff) >> 24
95
+ [head, extra_len_bits].pack('VV')
96
+ else
97
+ head = head_bits | len_bits | flags_bits
98
+ [head].pack('V')
99
+ end
91
100
  end
92
101
 
93
102
  class << self
@@ -392,6 +401,10 @@ module EM::Rserve
392
401
  def self.decode_nodes(buffer)
393
402
  head, buffer = buffer.unpack('Va*')
394
403
  type, flags, len = head_parameter(head)
404
+ if flags[:large]
405
+ long_len, buffer = buffer.unpack('Va*')
406
+ len = long_len << 24 | len
407
+ end
395
408
 
396
409
  # Cuts the buffer at the correct length and give away the remainder
397
410
  buffer, remainder = buffer.unpack("a#{len}a*")
@@ -1,5 +1,5 @@
1
1
  module EM
2
2
  module Rserve
3
- VERSION = "0.1.0"
3
+ VERSION = "0.1.1"
4
4
  end
5
5
  end
data/samples/assign.rb CHANGED
@@ -10,13 +10,25 @@ class DevelConnection < EM::Rserve::Connection
10
10
  def dump_sexp(msg)
11
11
  raise unless msg.parameters.size == 1
12
12
  root = msg.parameters.first
13
- pp root
14
13
  val = EM::Rserve::R::RtoRuby::Translator.r_to_ruby(root)
15
- p val
14
+ if val.respond_to? :size
15
+ if val.size > 100
16
+ puts "too large to dump: #{val.class}"
17
+ else
18
+ pp root
19
+ p val
20
+ end
21
+ else
22
+ pp root
23
+ p val
24
+ end
16
25
  end
17
26
 
18
27
  def dump_r_val(str)
19
28
  r_eval(str) do |req|
29
+ req.errback do |msg|
30
+ puts "could not dump"
31
+ end
20
32
  req.callback do |msg|
21
33
  dump_sexp msg
22
34
  end
@@ -38,11 +50,16 @@ class DevelConnection < EM::Rserve::Connection
38
50
  def loop_parse_r_val(str)
39
51
  r_eval(str) do |req|
40
52
  req.callback do |msg|
53
+ puts "callback> #{str}"
41
54
  raise unless msg.parameters.size == 1
42
55
  root = msg.parameters.first
43
- new_root = EM::Rserve::R::Sexp.parse(root.dump_sexp)
56
+ puts 'got parsed SEXP parameter'
44
57
  val1 = EM::Rserve::R::RtoRuby::Translator.r_to_ruby(root)
58
+ puts 'translated SEXP'
59
+ new_root = EM::Rserve::R::Sexp.parse(root.dump_sexp)
60
+ puts 'dumped SEXP'
45
61
  val2 = EM::Rserve::R::RtoRuby::Translator.r_to_ruby(new_root)
62
+ puts 're-translated dumped SEXP'
46
63
  if val1 == val2
47
64
  p "ok: #{str}"
48
65
  else
@@ -155,9 +172,14 @@ class DevelConnection < EM::Rserve::Connection
155
172
  def ready
156
173
  puts "ready"
157
174
 
158
- loop_parse_r_val '1+1i'
159
- loop_parse_r_val 'c(1:1000)'
160
- loop_parse_r_val 'c(1:10000000)'
175
+ #do_array_int((1 .. 10).to_a)
176
+ #do_array_int((1 .. 10000000).to_a)
177
+ loop_parse_r_val 'c(1:5)'
178
+ loop_parse_r_val "c(1:10000000)"
179
+ loop_parse_r_val 'table(c(1,2,3,2,2))'
180
+ loop_parse_r_val "data.frame(foo=c(1:8), bar=seq(100,800,100))"
181
+ loop_parse_r_val "data.frame(foo=c(1,2,3), bar=c(NA,FALSE,TRUE), row.names=c('foo','bar','baz'))"
182
+
161
183
 
162
184
  return
163
185
 
@@ -173,10 +195,6 @@ class DevelConnection < EM::Rserve::Connection
173
195
 
174
196
  return
175
197
 
176
- loop_parse_r_val 'c(1:5)'
177
- loop_parse_r_val 'table(c(1,2,3,2,2))'
178
- loop_parse_r_val "data.frame(foo=c(1:8), bar=seq(100,800,100))"
179
- loop_parse_r_val "data.frame(foo=c(1,2,3), bar=c(NA,FALSE,TRUE), row.names=c('foo','bar','baz'))"
180
198
 
181
199
  #do_int
182
200
  #do_double
metadata CHANGED
@@ -1,34 +1,23 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: em-rserve
3
- version: !ruby/object:Gem::Version
4
- hash: 27
5
- prerelease: false
6
- segments:
7
- - 0
8
- - 1
9
- - 0
10
- version: 0.1.0
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ prerelease:
11
6
  platform: ruby
12
- authors:
7
+ authors:
13
8
  - crapooze
14
9
  autorequire:
15
10
  bindir: bin
16
11
  cert_chain: []
17
-
18
- date: 2011-10-10 00:00:00 +02:00
19
- default_executable:
12
+ date: 2011-10-21 00:00:00.000000000Z
20
13
  dependencies: []
21
-
22
14
  description: Do evented stats with EventMachine and RServe
23
- email:
15
+ email:
24
16
  - crapooze@gmail.com
25
17
  executables: []
26
-
27
18
  extensions: []
28
-
29
19
  extra_rdoc_files: []
30
-
31
- files:
20
+ files:
32
21
  - .gitignore
33
22
  - Gemfile
34
23
  - README
@@ -63,39 +52,28 @@ files:
63
52
  - specs/parser_spec.rb
64
53
  - specs/ruby_to_r_translator_spec.rb
65
54
  - specs/spec_helper.rb
66
- has_rdoc: true
67
- homepage: ""
55
+ homepage: ''
68
56
  licenses: []
69
-
70
57
  post_install_message:
71
58
  rdoc_options: []
72
-
73
- require_paths:
59
+ require_paths:
74
60
  - lib
75
- required_ruby_version: !ruby/object:Gem::Requirement
61
+ required_ruby_version: !ruby/object:Gem::Requirement
76
62
  none: false
77
- requirements:
78
- - - ">="
79
- - !ruby/object:Gem::Version
80
- hash: 3
81
- segments:
82
- - 0
83
- version: "0"
84
- required_rubygems_version: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - ! '>='
65
+ - !ruby/object:Gem::Version
66
+ version: '0'
67
+ required_rubygems_version: !ruby/object:Gem::Requirement
85
68
  none: false
86
- requirements:
87
- - - ">="
88
- - !ruby/object:Gem::Version
89
- hash: 3
90
- segments:
91
- - 0
92
- version: "0"
69
+ requirements:
70
+ - - ! '>='
71
+ - !ruby/object:Gem::Version
72
+ version: '0'
93
73
  requirements: []
94
-
95
74
  rubyforge_project: em-rserve
96
- rubygems_version: 1.3.7
75
+ rubygems_version: 1.8.6
97
76
  signing_key:
98
77
  specification_version: 3
99
78
  summary: An EventMachine client for RServe
100
79
  test_files: []
101
-