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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e13b968103c3abf0b12a8470ed92fd1752383cce
4
- data.tar.gz: 12c63e4be210d0b344c4f0372194ad4032c89eab
3
+ metadata.gz: c71959cd30828a5ce4f4e195aa305cc6b39d0ee8
4
+ data.tar.gz: b92b60c638453174af654dfefa2a56a5f0e76971
5
5
  SHA512:
6
- metadata.gz: 41caf09bea96de9e666a3471c12c08205d22e2f677d6e02a18d39731e1a3c107ec9ff21ef68b40489ae53ed75f8f0f8e75cf1f2fec4a5bc75286c400b991b324
7
- data.tar.gz: f558277c7d4aa49f464167be145df963a2b47df57fc523060f9ed57c931c46da19f75f086a435f60fa9331b5d400058ed9fa79e0277db1ba8d97c2827985b6ea
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!
@@ -6,6 +6,7 @@ gem 'thin'
6
6
 
7
7
  gem 'opal', github: 'youchan/opal', branch: 'marshal-dump-bignum'
8
8
  gem 'opal-sprockets', github: 'opal/opal-sprockets'
9
+ gem 'drb-websocket'
9
10
 
10
11
  gem 'rake'
11
12
  gem 'sass'
@@ -1,5 +1,5 @@
1
1
  GIT
2
- remote: git://github.com/opal/opal-sprockets.git
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: git://github.com/youchan/opal.git
12
- revision: 79998074a820fd1e651bce1e8661245949648285
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
- eventmachine (1.2.3)
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
- sass (3.4.24)
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.1)
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.7)
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.14.6
93
+ 1.15.3
@@ -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: 9292,
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)
@@ -13,5 +13,7 @@ if RUBY_ENGINE == 'opal'
13
13
  require 'opal/drb/drb_conn'
14
14
  require 'opal/drb/drb_object'
15
15
  require 'opal/drb/drb_message'
16
+ require 'opal/drb/drb_server'
16
17
  require 'opal/drb/drb'
18
+ require 'opal/drb/invoke_method'
17
19
  end
@@ -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
@@ -53,11 +53,4 @@ module DRb
53
53
  @protocol.alive?
54
54
  end
55
55
  end
56
-
57
- def self.default_config
58
- {
59
- argc_limit: 256,
60
- load_limit: 256 * 102400
61
- }
62
- end
63
56
  end
@@ -1,6 +1,7 @@
1
1
  module DRb
2
2
  class DRbMessage
3
3
  def initialize(config)
4
+ config = DRb.default_config.merge(config || {})
4
5
  @load_limit = config[:load_limit]
5
6
  @argc_limit = config[:argc_limit]
6
7
  end
@@ -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 : nil
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 open(uri, config, first=true)
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, first=true)
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
+
@@ -1,5 +1,5 @@
1
1
  module Opal
2
2
  module DRb
3
- VERSION = "0.1.1"
3
+ VERSION = "0.2.0"
4
4
  end
5
5
  end
@@ -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
- post(@uri, stream.buf)
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 post(uri, data)
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.1.1
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-08-08 00:00:00.000000000 Z
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