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 +5 -2
- data/README +0 -1
- data/TODO +1 -1
- data/lib/em-rserve/pooler.rb +1 -0
- data/lib/em-rserve/qap1/header.rb +1 -4
- data/lib/em-rserve/qap1/rpack.rb +17 -6
- data/lib/em-rserve/r/sexp.rb +17 -4
- data/lib/em-rserve/version.rb +1 -1
- data/samples/assign.rb +28 -10
- metadata +21 -43
data/Gemfile
CHANGED
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
|
-
*
|
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
|
data/lib/em-rserve/pooler.rb
CHANGED
@@ -11,7 +11,7 @@ module EM::Rserve
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def message_length
|
14
|
-
length
|
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
|
data/lib/em-rserve/qap1/rpack.rb
CHANGED
@@ -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
|
-
|
13
|
-
|
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('
|
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
|
87
|
+
type = head & 0x000000bf
|
80
88
|
large = (head & DT_LARGE) > 0
|
81
|
-
len
|
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
|
-
|
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
|
data/lib/em-rserve/r/sexp.rb
CHANGED
@@ -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].
|
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
|
-
|
90
|
-
|
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*")
|
data/lib/em-rserve/version.rb
CHANGED
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
|
-
|
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
|
-
|
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
|
-
|
159
|
-
|
160
|
-
loop_parse_r_val 'c(1:
|
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
|
-
|
5
|
-
prerelease:
|
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
|
-
|
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
|
-
|
81
|
-
|
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
|
-
|
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.
|
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
|
-
|