opal-drb 0.1.1 → 0.2.0
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.
- checksums.yaml +4 -4
- data/README.md +15 -0
- data/example/Gemfile +1 -0
- data/example/Gemfile.lock +27 -8
- data/example/config.ru +6 -1
- data/example/drb_server.rb +16 -0
- data/lib/opal/drb.rb +2 -0
- data/lib/opal/drb/drb.rb +22 -10
- data/lib/opal/drb/drb_conn.rb +0 -7
- data/lib/opal/drb/drb_message.rb +1 -0
- data/lib/opal/drb/drb_object.rb +6 -1
- data/lib/opal/drb/drb_protocol.rb +17 -6
- data/lib/opal/drb/drb_server.rb +33 -0
- data/lib/opal/drb/invoke_method.rb +85 -0
- data/lib/opal/drb/version.rb +1 -1
- data/lib/opal/drb/websocket.rb +72 -4
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c71959cd30828a5ce4f4e195aa305cc6b39d0ee8
|
4
|
+
data.tar.gz: b92b60c638453174af654dfefa2a56a5f0e76971
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6f0ddc332aba0a9625f3c2dd9ecfa625489c014f89eb3d79f8cef1256be277efe29cd43c1f89df6fffeaa557f8691891384001a9a5cabc3ec1bcb2e7eabda03e
|
7
|
+
data.tar.gz: a368f158fb6aec43bdf87ccd1bad0bf58c7b975d4825f24ba7b103b2f5330843a1260760c85e5579871f3a278ab8ee7594e6a4c5b18fbf7571f3012339cb71d6
|
data/README.md
CHANGED
@@ -2,3 +2,18 @@
|
|
2
2
|
|
3
3
|
A dRuby implementation for Opal.
|
4
4
|
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
$ gem install opal-drb
|
8
|
+
|
9
|
+
## How to run example
|
10
|
+
|
11
|
+
$ git clone https://github.com/youchan/opal-drb
|
12
|
+
$ cd opal-drb/example
|
13
|
+
$ bundle install
|
14
|
+
$ bundle exec rackup
|
15
|
+
|
16
|
+
Open following url and watch development console.
|
17
|
+
|
18
|
+
http://localhost:1234
|
19
|
+
=> ACK!
|
data/example/Gemfile
CHANGED
data/example/Gemfile.lock
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
GIT
|
2
|
-
remote:
|
2
|
+
remote: https://github.com/opal/opal-sprockets.git
|
3
3
|
revision: a063dffd884b495ed0c54b4c3b0b1cacc4abb322
|
4
4
|
specs:
|
5
5
|
opal-sprockets (0.4.1.0.11.0.rc1.3.1.beta2)
|
@@ -8,8 +8,8 @@ GIT
|
|
8
8
|
tilt (>= 1.4)
|
9
9
|
|
10
10
|
GIT
|
11
|
-
remote:
|
12
|
-
revision:
|
11
|
+
remote: https://github.com/youchan/opal.git
|
12
|
+
revision: 1a5a59b66a0469c73c18e90c66591a7a66421de5
|
13
13
|
branch: marshal-dump-bignum
|
14
14
|
specs:
|
15
15
|
opal (0.11.0.rc1)
|
@@ -25,7 +25,15 @@ GEM
|
|
25
25
|
backports (3.8.0)
|
26
26
|
concurrent-ruby (1.0.5)
|
27
27
|
daemons (1.2.4)
|
28
|
-
|
28
|
+
drb-websocket (0.2.0)
|
29
|
+
faye-websocket
|
30
|
+
rack
|
31
|
+
thin
|
32
|
+
eventmachine (1.2.5)
|
33
|
+
faye-websocket (0.10.7)
|
34
|
+
eventmachine (>= 0.12.0)
|
35
|
+
websocket-driver (>= 0.5.1)
|
36
|
+
ffi (1.9.18)
|
29
37
|
hike (1.2.3)
|
30
38
|
multi_json (1.12.1)
|
31
39
|
mustermann (1.0.0)
|
@@ -35,7 +43,14 @@ GEM
|
|
35
43
|
rack-protection (2.0.0)
|
36
44
|
rack
|
37
45
|
rake (12.0.0)
|
38
|
-
|
46
|
+
rb-fsevent (0.10.2)
|
47
|
+
rb-inotify (0.9.10)
|
48
|
+
ffi (>= 0.5.0, < 2)
|
49
|
+
sass (3.5.1)
|
50
|
+
sass-listen (~> 4.0.0)
|
51
|
+
sass-listen (4.0.0)
|
52
|
+
rb-fsevent (~> 0.9, >= 0.9.4)
|
53
|
+
rb-inotify (~> 0.9, >= 0.9.7)
|
39
54
|
sinatra (2.0.0)
|
40
55
|
mustermann (~> 1.0)
|
41
56
|
rack (~> 2.0)
|
@@ -52,16 +67,20 @@ GEM
|
|
52
67
|
sprockets (3.7.1)
|
53
68
|
concurrent-ruby (~> 1.0)
|
54
69
|
rack (> 1, < 3)
|
55
|
-
thin (1.7.
|
70
|
+
thin (1.7.2)
|
56
71
|
daemons (~> 1.0, >= 1.0.9)
|
57
72
|
eventmachine (~> 1.0, >= 1.0.4)
|
58
73
|
rack (>= 1, < 3)
|
59
|
-
tilt (2.0.
|
74
|
+
tilt (2.0.8)
|
75
|
+
websocket-driver (0.6.5)
|
76
|
+
websocket-extensions (>= 0.1.0)
|
77
|
+
websocket-extensions (0.1.2)
|
60
78
|
|
61
79
|
PLATFORMS
|
62
80
|
ruby
|
63
81
|
|
64
82
|
DEPENDENCIES
|
83
|
+
drb-websocket
|
65
84
|
opal!
|
66
85
|
opal-sprockets!
|
67
86
|
rake
|
@@ -71,4 +90,4 @@ DEPENDENCIES
|
|
71
90
|
thin
|
72
91
|
|
73
92
|
BUNDLED WITH
|
74
|
-
1.
|
93
|
+
1.15.3
|
data/example/config.ru
CHANGED
@@ -1,12 +1,15 @@
|
|
1
1
|
require 'bundler/setup'
|
2
2
|
Bundler.require(:default)
|
3
3
|
|
4
|
+
require 'drb/websocket/server'
|
5
|
+
|
4
6
|
require_relative 'server'
|
5
7
|
|
6
8
|
app = Rack::Builder.app do
|
7
9
|
server = Server.new(host: 'localhost')
|
8
10
|
|
9
11
|
map '/' do
|
12
|
+
use DRb::WebSocket::RackApp
|
10
13
|
run server
|
11
14
|
end
|
12
15
|
|
@@ -19,10 +22,12 @@ app = Rack::Builder.app do
|
|
19
22
|
end
|
20
23
|
end
|
21
24
|
|
25
|
+
require_relative './drb_server'
|
26
|
+
|
22
27
|
Rack::Server.start({
|
23
28
|
app: app,
|
24
29
|
server: 'thin',
|
25
30
|
Host: '0.0.0.0',
|
26
|
-
Port:
|
31
|
+
Port: 1234,
|
27
32
|
signals: false,
|
28
33
|
})
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'drb/drb'
|
2
|
+
require 'drb/websocket/server'
|
3
|
+
|
4
|
+
class SampleObject
|
5
|
+
def test
|
6
|
+
"ACK!"
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
class SampleFactory
|
11
|
+
def self.get
|
12
|
+
DRbObject.new(SampleObject.new)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
DRb.start_service("ws://127.0.0.1:1234", SampleFactory)
|
data/lib/opal/drb.rb
CHANGED
data/lib/opal/drb/drb.rb
CHANGED
@@ -28,16 +28,6 @@ module DRb
|
|
28
28
|
attr_reader :reason
|
29
29
|
end
|
30
30
|
|
31
|
-
class DRbIdConv
|
32
|
-
def to_obj(ref)
|
33
|
-
ObjectSpace._id2ref(ref)
|
34
|
-
end
|
35
|
-
|
36
|
-
def to_id(obj)
|
37
|
-
obj.nil? ? nil : obj.__id__
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
31
|
module DRbUndumped
|
42
32
|
def _dump(dummy)
|
43
33
|
raise TypeError, 'can\'t dump'
|
@@ -106,4 +96,26 @@ module DRb
|
|
106
96
|
end
|
107
97
|
end
|
108
98
|
|
99
|
+
def self.to_obj(ref)
|
100
|
+
DRb::DRbObject.id2ref[ref]
|
101
|
+
end
|
102
|
+
|
103
|
+
def self.to_id(obj)
|
104
|
+
obj.nil? ? nil : obj.__id__
|
105
|
+
end
|
106
|
+
|
107
|
+
def self.current_server
|
108
|
+
@callback_server
|
109
|
+
end
|
110
|
+
|
111
|
+
def self.start_service(uri)
|
112
|
+
@callback_server = DRbServer.new(uri, {})
|
113
|
+
end
|
114
|
+
|
115
|
+
def self.default_config
|
116
|
+
{
|
117
|
+
argc_limit: 256,
|
118
|
+
load_limit: 256 * 102400
|
119
|
+
}
|
120
|
+
end
|
109
121
|
end
|
data/lib/opal/drb/drb_conn.rb
CHANGED
data/lib/opal/drb/drb_message.rb
CHANGED
data/lib/opal/drb/drb_object.rb
CHANGED
@@ -30,8 +30,9 @@ module DRb
|
|
30
30
|
@uri, option = DRbProtocol.uri_option(uri, DRb::default_config)
|
31
31
|
@ref = DRbURIOption.new(option) unless option.nil?
|
32
32
|
else
|
33
|
-
@uri = uri ? uri :
|
33
|
+
@uri = uri ? uri : DRb.current_server.uri
|
34
34
|
@ref = obj ? DRb.to_id(obj) : nil
|
35
|
+
DRbObject.id2ref[@ref] = obj
|
35
36
|
end
|
36
37
|
end
|
37
38
|
|
@@ -46,6 +47,10 @@ module DRb
|
|
46
47
|
undef :to_s
|
47
48
|
undef :to_a if respond_to?(:to_a)
|
48
49
|
|
50
|
+
def self.id2ref
|
51
|
+
@id2ref ||= {}
|
52
|
+
end
|
53
|
+
|
49
54
|
def respond_to?(msg_id, priv=false)
|
50
55
|
case msg_id
|
51
56
|
when :_dump
|
@@ -9,7 +9,22 @@ module DRb
|
|
9
9
|
end
|
10
10
|
module_function :add_protocol
|
11
11
|
|
12
|
-
def
|
12
|
+
def open_server(uri, config)
|
13
|
+
@protocol.each do |prot|
|
14
|
+
begin
|
15
|
+
return prot.open_server(uri, config)
|
16
|
+
rescue DRbBadScheme
|
17
|
+
rescue DRbConnError
|
18
|
+
raise($!)
|
19
|
+
rescue
|
20
|
+
raise(DRbConnError, "#{uri} - #{$!.inspect}")
|
21
|
+
end
|
22
|
+
end
|
23
|
+
raise DRbBadURI, 'can\'t parse uri:' + uri
|
24
|
+
end
|
25
|
+
module_function :open_server
|
26
|
+
|
27
|
+
def open(uri, config)
|
13
28
|
@protocol.each do |prot|
|
14
29
|
begin
|
15
30
|
return prot.open(uri, config)
|
@@ -24,7 +39,7 @@ module DRb
|
|
24
39
|
end
|
25
40
|
module_function :open
|
26
41
|
|
27
|
-
def uri_option(uri, config
|
42
|
+
def uri_option(uri, config)
|
28
43
|
@protocol.each do |prot|
|
29
44
|
begin
|
30
45
|
uri, opt = prot.uri_option(uri, config)
|
@@ -32,10 +47,6 @@ module DRb
|
|
32
47
|
rescue DRbBadScheme
|
33
48
|
end
|
34
49
|
end
|
35
|
-
if first && (config[:auto_load] != false)
|
36
|
-
auto_load(uri)
|
37
|
-
return uri_option(uri, config, false)
|
38
|
-
end
|
39
50
|
raise DRbBadURI, 'can\'t parse uri:' + uri
|
40
51
|
end
|
41
52
|
module_function :uri_option
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module DRb
|
2
|
+
class DRbServer
|
3
|
+
attr_reader :uri
|
4
|
+
|
5
|
+
def initialize(uri)
|
6
|
+
@uri = uri
|
7
|
+
@protocol = DRbProtocol.open_server(@uri)
|
8
|
+
run
|
9
|
+
end
|
10
|
+
|
11
|
+
def run
|
12
|
+
@protocol.accept do |client|
|
13
|
+
begin
|
14
|
+
succ = false
|
15
|
+
invoke_method = InvokeMethod.new(self, client)
|
16
|
+
succ, result = invoke_method.perform
|
17
|
+
print_error(result) unless succ
|
18
|
+
client.send_reply(succ, result)
|
19
|
+
rescue Exception => e
|
20
|
+
print_error(e)
|
21
|
+
ensure
|
22
|
+
client.close unless succ
|
23
|
+
break unless succ
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def print_error(e)
|
29
|
+
puts e.message
|
30
|
+
p e.backtrace
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
class InvokeMethod
|
2
|
+
def initialize(drb_server, client)
|
3
|
+
@drb_server = drb_server
|
4
|
+
@client = client
|
5
|
+
end
|
6
|
+
|
7
|
+
def perform
|
8
|
+
@result = nil
|
9
|
+
@succ = false
|
10
|
+
|
11
|
+
setup_message
|
12
|
+
|
13
|
+
if @block
|
14
|
+
@result = perform_with_block
|
15
|
+
else
|
16
|
+
@result = perform_without_block
|
17
|
+
end
|
18
|
+
|
19
|
+
@succ = true
|
20
|
+
if @msg_id == :to_ary && @result.class == Array
|
21
|
+
@result = DRbArray.new(@result)
|
22
|
+
end
|
23
|
+
return @succ, @result
|
24
|
+
rescue StandardError, ScriptError, Interrupt
|
25
|
+
@result = $!
|
26
|
+
return @succ, @result
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
def init_with_client
|
31
|
+
obj, msg, argv, block = @client.recv_request
|
32
|
+
@obj = obj
|
33
|
+
@msg_id = msg.intern
|
34
|
+
@argv = argv
|
35
|
+
@block = block
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
def any_to_s(obj)
|
40
|
+
obj.to_s + ":#{obj.class}"
|
41
|
+
rescue
|
42
|
+
"#<#{obj.class}:0x#{obj.__id__.to_s(16)}>"
|
43
|
+
end
|
44
|
+
|
45
|
+
def check_insecure_method(obj, msg_id)
|
46
|
+
return true if Proc === obj && msg_id == :__drb_yield
|
47
|
+
raise(ArgumentError, "#{any_to_s(msg_id)} is not a symbol") unless Symbol == msg_id.class
|
48
|
+
raise(SecurityError, "insecure method `#{msg_id}'") if insecure_method?(msg_id)
|
49
|
+
|
50
|
+
if obj.private_methods.include?(msg_id)
|
51
|
+
desc = any_to_s(obj)
|
52
|
+
raise NoMethodError, "private method `#{msg_id}' called for #{desc}"
|
53
|
+
else
|
54
|
+
true
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def setup_message
|
59
|
+
init_with_client
|
60
|
+
check_insecure_method(@obj, @msg_id)
|
61
|
+
end
|
62
|
+
|
63
|
+
def perform_without_block
|
64
|
+
if Proc === @obj && @msg_id == :__drb_yield
|
65
|
+
if @argv.size == 1
|
66
|
+
ary = @argv
|
67
|
+
else
|
68
|
+
ary = [@argv]
|
69
|
+
end
|
70
|
+
ary.collect(&@obj)[0]
|
71
|
+
else
|
72
|
+
@obj.__send__(@msg_id, *@argv)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
INSECURE_METHOD = [
|
77
|
+
:__send__
|
78
|
+
]
|
79
|
+
|
80
|
+
# Has a method been included in the list of insecure methods?
|
81
|
+
def insecure_method?(msg_id)
|
82
|
+
INSECURE_METHOD.include?(msg_id)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
data/lib/opal/drb/version.rb
CHANGED
data/lib/opal/drb/websocket.rb
CHANGED
@@ -75,19 +75,87 @@ module DRb
|
|
75
75
|
end
|
76
76
|
|
77
77
|
def self.open(uri, config)
|
78
|
-
unless uri =~ /^ws:\/\/(.*?):(\d+)(
|
78
|
+
unless uri =~ /^ws:\/\/(.*?):(\d+)(\/(.*))?$/
|
79
79
|
raise(DRbBadScheme, uri) unless uri =~ /^ws:/
|
80
80
|
raise(DRbBadURI, 'can\'t parse uri:' + uri)
|
81
81
|
end
|
82
82
|
ClientSide.new(uri, config)
|
83
83
|
end
|
84
84
|
|
85
|
+
def self.open_server(uri, config)
|
86
|
+
unless uri =~ /^ws:\/\/(.*?):(\d+)(\/(.*))?$/
|
87
|
+
raise(DRbBadScheme, uri) unless uri =~ /^ws:/
|
88
|
+
raise(DRbBadURI, 'can\'t parse uri:' + uri)
|
89
|
+
end
|
90
|
+
Server.new(uri, config)
|
91
|
+
end
|
92
|
+
|
93
|
+
class Server
|
94
|
+
attr_reader :uri
|
95
|
+
|
96
|
+
def initialize(uri, config)
|
97
|
+
@uri = uri
|
98
|
+
@config = config
|
99
|
+
end
|
100
|
+
|
101
|
+
def close
|
102
|
+
u = URI.parse(@uri)
|
103
|
+
RackApp.close("#{u.host}:#{u.port}")
|
104
|
+
end
|
105
|
+
|
106
|
+
def accept
|
107
|
+
ws = ::WebSocket.new(uri)
|
108
|
+
ws.onmessage do |event|
|
109
|
+
stream = StrStream.new(event.data.to_s)
|
110
|
+
server_side = ServerSide.new(stream, @config, uri)
|
111
|
+
yield server_side
|
112
|
+
ws.send(`new Uint8Array(#{server_side.reply.bytes.each_slice(2).map(&:first)}).buffer`)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
class ServerSide
|
118
|
+
attr_reader :uri, :reply
|
119
|
+
|
120
|
+
def initialize(stream, config, uri)
|
121
|
+
@uri = uri
|
122
|
+
@config = config
|
123
|
+
@msg = DRbMessage.new(@config)
|
124
|
+
@req_stream = stream
|
125
|
+
end
|
126
|
+
|
127
|
+
def close
|
128
|
+
end
|
129
|
+
|
130
|
+
def alive?; false; end
|
131
|
+
|
132
|
+
def recv_request
|
133
|
+
begin
|
134
|
+
@msg.recv_request(@req_stream)
|
135
|
+
rescue
|
136
|
+
close
|
137
|
+
raise $!
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
def send_reply(succ, result)
|
142
|
+
begin
|
143
|
+
stream = StrStream.new
|
144
|
+
@msg.send_reply(stream, succ, result)
|
145
|
+
@reply = stream.buf
|
146
|
+
rescue
|
147
|
+
close
|
148
|
+
raise $!
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
85
153
|
class ClientSide
|
86
154
|
def initialize(uri, config)
|
87
155
|
@uri = uri
|
88
156
|
@res = nil
|
89
157
|
@config = config
|
90
|
-
@msg = DRbMessage.new(config)
|
158
|
+
@msg = DRbMessage.new(@config)
|
91
159
|
@proxy = ENV['HTTP_PROXY']
|
92
160
|
end
|
93
161
|
|
@@ -101,7 +169,7 @@ module DRb
|
|
101
169
|
def send_request(ref, msg_id, *arg, &b)
|
102
170
|
stream = StrStream.new
|
103
171
|
@msg.send_request(stream, ref, msg_id, *arg, &b)
|
104
|
-
|
172
|
+
send(@uri, stream.buf)
|
105
173
|
end
|
106
174
|
|
107
175
|
def recv_reply(reply_stream)
|
@@ -109,7 +177,7 @@ module DRb
|
|
109
177
|
@msg.recv_reply(reply_stream)
|
110
178
|
end
|
111
179
|
|
112
|
-
def
|
180
|
+
def send(uri, data)
|
113
181
|
promise = Promise.new
|
114
182
|
@ws = ::WebSocket.new(uri)
|
115
183
|
@ws.onmessage do |event|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: opal-drb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- youchan
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-09-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: opal
|
@@ -87,6 +87,7 @@ files:
|
|
87
87
|
- example/assets/css/application.scss
|
88
88
|
- example/bin/console
|
89
89
|
- example/config.ru
|
90
|
+
- example/drb_server.rb
|
90
91
|
- example/server.rb
|
91
92
|
- example/views/index.erb
|
92
93
|
- lib/opal/drb.rb
|
@@ -95,6 +96,8 @@ files:
|
|
95
96
|
- lib/opal/drb/drb_message.rb
|
96
97
|
- lib/opal/drb/drb_object.rb
|
97
98
|
- lib/opal/drb/drb_protocol.rb
|
99
|
+
- lib/opal/drb/drb_server.rb
|
100
|
+
- lib/opal/drb/invoke_method.rb
|
98
101
|
- lib/opal/drb/version.rb
|
99
102
|
- lib/opal/drb/websocket.rb
|
100
103
|
- opal-drb.gemspec
|