opal-drb 0.1.1 → 0.2.0

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