rbgo 0.2.8 → 0.2.9
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/.gitignore +1 -0
- data/lib/rbgo/actor.rb +5 -3
- data/lib/rbgo/corun.rb +69 -37
- data/lib/rbgo/io_machine.rb +86 -0
- data/lib/rbgo/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4811ffce7c609abea9507fc023c9383121d232d6b79cb221e1ac62980ea879a0
|
4
|
+
data.tar.gz: 297e658752df154a7e5202cd2d6801c5b4aef3399229710f1b37bc0e6e025868
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 70ba89e8bb29f007a40e51d715306da0cec8ebb9c71331e2f60d08e46005ca12d44eb5e18dace1b531f758b226abe40e1c31f7101d78c95a3864db2410d30c40
|
7
|
+
data.tar.gz: 8ffd9db409f9714c7d160d994a19f38d0ffbacd0fb115a77ade48574ba326f73a40b8389a105703386fa524676cfa5b318acc663c37e72d71510f421317f9060
|
data/.gitignore
CHANGED
data/lib/rbgo/actor.rb
CHANGED
@@ -4,7 +4,6 @@ require 'thread'
|
|
4
4
|
module Rbgo
|
5
5
|
class Actor
|
6
6
|
private
|
7
|
-
|
8
7
|
attr_accessor :mail_box
|
9
8
|
|
10
9
|
public
|
@@ -35,9 +34,12 @@ module Rbgo
|
|
35
34
|
private
|
36
35
|
|
37
36
|
def start_msg_loop
|
38
|
-
CoRun::Routine.new(new_thread: true) do
|
39
|
-
|
37
|
+
CoRun::Routine.new(new_thread: true, queue_tag: :default) do
|
38
|
+
loop do
|
39
|
+
break if mail_box.closed?
|
40
|
+
msg = mail_box.deq
|
40
41
|
handler.call(msg, self) rescue nil
|
42
|
+
Fiber.yield
|
41
43
|
end
|
42
44
|
end
|
43
45
|
end
|
data/lib/rbgo/corun.rb
CHANGED
@@ -44,6 +44,24 @@ module Rbgo
|
|
44
44
|
end
|
45
45
|
end
|
46
46
|
|
47
|
+
def self.accept_from(sock)
|
48
|
+
if is_in_corun_fiber?
|
49
|
+
receipt = Scheduler.instance.io_machine.do_socket_accept(sock)
|
50
|
+
Fiber.yield [YIELD_IO_OPERATION, receipt]
|
51
|
+
else
|
52
|
+
sock.accept
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def self.connect_to(sock, remote_sockaddr:)
|
57
|
+
if is_in_corun_fiber?
|
58
|
+
receipt = Scheduler.instance.io_machine.do_socket_connect(sock, remote_sockaddr: remote_sockaddr)
|
59
|
+
Fiber.yield [YIELD_IO_OPERATION, receipt]
|
60
|
+
else
|
61
|
+
sock.connect(remote_sockaddr)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
47
65
|
def self.write_to(io, str:)
|
48
66
|
if is_in_corun_fiber?
|
49
67
|
receipt = Scheduler.instance.io_machine.do_write(io, str: str)
|
@@ -65,29 +83,10 @@ module Rbgo
|
|
65
83
|
|
66
84
|
attr_accessor :args, :blk, :fiber, :io_receipt
|
67
85
|
|
68
|
-
def initialize(*args, new_thread: false, &blk)
|
86
|
+
def initialize(*args, new_thread: false, queue_tag: :default, &blk) # :default :none :actor
|
69
87
|
self.args = args
|
70
88
|
self.blk = blk
|
71
|
-
|
72
|
-
Thread.new do
|
73
|
-
Thread.current.report_on_exception = false
|
74
|
-
self.fiber = Fiber.new do |args|
|
75
|
-
blk.call(*args)
|
76
|
-
end
|
77
|
-
|
78
|
-
begin
|
79
|
-
while fiber.alive?
|
80
|
-
fiber.resume(*args)
|
81
|
-
end
|
82
|
-
rescue Exception => ex
|
83
|
-
self.error = ex
|
84
|
-
STDERR.puts ex
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
|
-
else
|
89
|
-
Scheduler.instance.schedule(self)
|
90
|
-
end
|
89
|
+
Scheduler.instance.schedule(self, new_thread: new_thread, queue_tag: queue_tag)
|
91
90
|
end
|
92
91
|
|
93
92
|
def perform
|
@@ -138,7 +137,7 @@ module Rbgo
|
|
138
137
|
private
|
139
138
|
|
140
139
|
attr_accessor :thread_pool
|
141
|
-
attr_accessor :
|
140
|
+
attr_accessor :task_queues, :task_queues_mutex
|
142
141
|
attr_accessor :msg_queue
|
143
142
|
attr_accessor :supervisor_thread
|
144
143
|
attr_accessor :io_machine_init_once
|
@@ -147,20 +146,21 @@ module Rbgo
|
|
147
146
|
self.num_thread = System::CPU.count rescue 8
|
148
147
|
self.thread_pool = []
|
149
148
|
|
150
|
-
self.msg_queue
|
151
|
-
self.
|
149
|
+
self.msg_queue = Queue.new
|
150
|
+
self.task_queues = Hash.new { |hash, key| hash[key] = Queue.new }
|
151
|
+
self.task_queues_mutex = Mutex.new
|
152
152
|
|
153
153
|
self.check_interval = 0.1
|
154
154
|
|
155
155
|
self.io_machine_init_once = Once.new
|
156
156
|
|
157
|
-
msg_queue << :init
|
157
|
+
msg_queue << [:init]
|
158
158
|
create_supervisor_thread
|
159
159
|
generate_check_msg
|
160
160
|
end
|
161
161
|
|
162
162
|
# only called by supervisor thread
|
163
|
-
def create_thread
|
163
|
+
def create_thread(run_for_once: false, queue_tag: :default, init_task: nil)
|
164
164
|
begin
|
165
165
|
thread_pool << Thread.new do
|
166
166
|
Thread.current.report_on_exception = false
|
@@ -169,6 +169,8 @@ module Rbgo
|
|
169
169
|
yield_task_queue = Queue.new
|
170
170
|
pending_io_task_queue = Queue.new
|
171
171
|
local_task_queue = Queue.new
|
172
|
+
task_queue = get_queue(queue_tag)
|
173
|
+
local_task_queue << init_task if init_task
|
172
174
|
loop do
|
173
175
|
task = nil
|
174
176
|
if local_task_queue.empty?
|
@@ -218,14 +220,20 @@ module Rbgo
|
|
218
220
|
yield_task_queue << task
|
219
221
|
end
|
220
222
|
|
221
|
-
|
222
|
-
yield_task_queue.empty? &&
|
223
|
-
|
224
|
-
|
223
|
+
if run_for_once
|
224
|
+
should_exit = yield_task_queue.empty? &&
|
225
|
+
pending_io_task_queue.empty? &&
|
226
|
+
local_task_queue.empty?
|
227
|
+
else
|
228
|
+
should_exit = Thread.current.thread_variable_get(:should_exit) &&
|
229
|
+
yield_task_queue.empty? &&
|
230
|
+
pending_io_task_queue.empty? &&
|
231
|
+
local_task_queue.empty?
|
232
|
+
end
|
225
233
|
break if should_exit
|
226
234
|
end
|
227
235
|
ensure
|
228
|
-
msg_queue << :thread_exit unless should_exit
|
236
|
+
msg_queue << [:thread_exit] unless should_exit
|
229
237
|
end
|
230
238
|
end
|
231
239
|
rescue Exception => ex
|
@@ -239,9 +247,13 @@ module Rbgo
|
|
239
247
|
begin
|
240
248
|
loop do
|
241
249
|
msg = msg_queue.deq
|
242
|
-
case msg
|
250
|
+
case msg[0]
|
243
251
|
when :thread_exit, :init, :check
|
244
252
|
check_thread_pool
|
253
|
+
when :new_thread
|
254
|
+
task = msg[1]
|
255
|
+
tag = msg[2]
|
256
|
+
create_thread(run_for_once: true, queue_tag: tag, init_task: task)
|
245
257
|
end
|
246
258
|
end
|
247
259
|
ensure
|
@@ -255,7 +267,7 @@ module Rbgo
|
|
255
267
|
Thread.new do
|
256
268
|
begin
|
257
269
|
loop do
|
258
|
-
msg_queue << :check
|
270
|
+
msg_queue << [:check]
|
259
271
|
sleep check_interval
|
260
272
|
end
|
261
273
|
ensure
|
@@ -295,10 +307,21 @@ module Rbgo
|
|
295
307
|
nil
|
296
308
|
end
|
297
309
|
|
310
|
+
def get_queue(tag)
|
311
|
+
task_queues_mutex.synchronize do
|
312
|
+
task_queues[tag]
|
313
|
+
end
|
314
|
+
end
|
315
|
+
|
298
316
|
public
|
299
317
|
|
300
|
-
def schedule(routine)
|
301
|
-
|
318
|
+
def schedule(routine, new_thread: false, queue_tag: :default)
|
319
|
+
if new_thread
|
320
|
+
msg_queue << [:new_thread, routine, queue_tag]
|
321
|
+
else
|
322
|
+
queue = get_queue(queue_tag)
|
323
|
+
queue << routine
|
324
|
+
end
|
302
325
|
nil
|
303
326
|
end
|
304
327
|
end
|
@@ -309,11 +332,11 @@ module Rbgo
|
|
309
332
|
module CoRunExtensions
|
310
333
|
refine Object do
|
311
334
|
def go(*args, &blk)
|
312
|
-
CoRun::Routine.new(*args, new_thread: false, &blk)
|
335
|
+
CoRun::Routine.new(*args, new_thread: false, queue_tag: :default, &blk)
|
313
336
|
end
|
314
337
|
|
315
338
|
def go!(*args, &blk)
|
316
|
-
CoRun::Routine.new(*args, new_thread: true, &blk)
|
339
|
+
CoRun::Routine.new(*args, new_thread: true, queue_tag: :none, &blk)
|
317
340
|
end
|
318
341
|
end
|
319
342
|
|
@@ -333,7 +356,16 @@ module Rbgo
|
|
333
356
|
def yield_write(str)
|
334
357
|
CoRun.write_to(self, str: str)
|
335
358
|
end
|
359
|
+
end
|
360
|
+
|
361
|
+
refine Socket do
|
362
|
+
def yield_accept
|
363
|
+
CoRun.accept_from(self)
|
364
|
+
end
|
336
365
|
|
366
|
+
def yield_connect(remote_sockaddr)
|
367
|
+
CoRun.connect_to(self, remote_sockaddr: remote_sockaddr)
|
368
|
+
end
|
337
369
|
end
|
338
370
|
end
|
339
371
|
end
|
data/lib/rbgo/io_machine.rb
CHANGED
@@ -66,6 +66,19 @@ module Rbgo
|
|
66
66
|
receipt
|
67
67
|
end
|
68
68
|
|
69
|
+
def do_socket_accept(sock)
|
70
|
+
op = [:register_socket_accept, sock]
|
71
|
+
receipt = IOReceipt.new(op)
|
72
|
+
actor.send_msg(receipt)
|
73
|
+
receipt
|
74
|
+
end
|
75
|
+
|
76
|
+
def do_socket_connect(sock, remote_sockaddr:)
|
77
|
+
op = [:register_socket_connect, sock, remote_sockaddr]
|
78
|
+
receipt = IOReceipt.new(op)
|
79
|
+
actor.send_msg(receipt)
|
80
|
+
receipt
|
81
|
+
end
|
69
82
|
|
70
83
|
def close
|
71
84
|
actor.close
|
@@ -102,6 +115,10 @@ module Rbgo
|
|
102
115
|
handle_read_partial_msg(receipt, actor)
|
103
116
|
when :register_write
|
104
117
|
handle_write_msg(receipt, actor)
|
118
|
+
when :register_socket_accept
|
119
|
+
handle_socket_accept_msg(receipt, actor)
|
120
|
+
when :register_socket_connect
|
121
|
+
handle_socket_connect_msg(receipt, actor)
|
105
122
|
end
|
106
123
|
end #end of actor
|
107
124
|
|
@@ -127,6 +144,74 @@ module Rbgo
|
|
127
144
|
nil
|
128
145
|
end
|
129
146
|
|
147
|
+
def handle_socket_connect_msg(receipt, actor)
|
148
|
+
|
149
|
+
op = receipt.registered_op
|
150
|
+
sock = op[1]
|
151
|
+
remote_sockaddr = op[2]
|
152
|
+
res = nil
|
153
|
+
|
154
|
+
monitor = register(receipt, interest: :w)
|
155
|
+
return if monitor.nil?
|
156
|
+
|
157
|
+
monitor.value ||= []
|
158
|
+
monitor.value[1] = proc do
|
159
|
+
notify_blk = proc do
|
160
|
+
monitors.delete(monitor.io)
|
161
|
+
monitor.close
|
162
|
+
receipt.res = res
|
163
|
+
receipt.notify
|
164
|
+
end
|
165
|
+
catch :exit do
|
166
|
+
begin
|
167
|
+
res = sock.connect_nonblock(remote_sockaddr, exception: false)
|
168
|
+
rescue Exception => ex
|
169
|
+
notify_blk.call
|
170
|
+
STDERR.puts ex
|
171
|
+
throw :exit
|
172
|
+
end
|
173
|
+
if res == :wait_writable
|
174
|
+
throw :exit
|
175
|
+
end
|
176
|
+
notify_blk.call
|
177
|
+
end
|
178
|
+
end
|
179
|
+
monitor.value[1].call
|
180
|
+
actor.send_msg :do_select
|
181
|
+
end
|
182
|
+
|
183
|
+
def handle_socket_accept_msg(receipt, actor)
|
184
|
+
op = receipt.registered_op
|
185
|
+
sock = op[1]
|
186
|
+
res = nil
|
187
|
+
|
188
|
+
monitor = register(receipt, interest: :r)
|
189
|
+
return if monitor.nil?
|
190
|
+
|
191
|
+
monitor.value ||= []
|
192
|
+
monitor.value[0] = proc do
|
193
|
+
notify_blk = proc do
|
194
|
+
monitors.delete(monitor.io)
|
195
|
+
monitor.close
|
196
|
+
receipt.res = res
|
197
|
+
receipt.notify
|
198
|
+
end
|
199
|
+
catch :exit do
|
200
|
+
begin
|
201
|
+
res = sock.accept_nonblock(exception: false)
|
202
|
+
rescue Exception => ex
|
203
|
+
notify_blk.call
|
204
|
+
STDERR.puts ex
|
205
|
+
throw :exit
|
206
|
+
end
|
207
|
+
if res == :wait_readable
|
208
|
+
throw :exit
|
209
|
+
end
|
210
|
+
notify_blk.call
|
211
|
+
end
|
212
|
+
end
|
213
|
+
actor.send_msg :do_select
|
214
|
+
end
|
130
215
|
|
131
216
|
def handle_read_partial_msg(receipt, actor)
|
132
217
|
op = receipt.registered_op
|
@@ -362,6 +447,7 @@ module Rbgo
|
|
362
447
|
STDERR.puts ex
|
363
448
|
end
|
364
449
|
end
|
450
|
+
monitor.value[1].call
|
365
451
|
actor.send_msg :do_select
|
366
452
|
end
|
367
453
|
|
data/lib/rbgo/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rbgo
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.9
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Wang Yin
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-08-
|
11
|
+
date: 2019-08-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: system
|