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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 88f583cbc3309a81e56fa7388a94b12e221be18ee671e40075dc1d2a531a1387
4
- data.tar.gz: 66adc91902e07196656a01fbba5bd5c4f3e451f670b3da62ea1f2b9079b8f225
3
+ metadata.gz: 4811ffce7c609abea9507fc023c9383121d232d6b79cb221e1ac62980ea879a0
4
+ data.tar.gz: 297e658752df154a7e5202cd2d6801c5b4aef3399229710f1b37bc0e6e025868
5
5
  SHA512:
6
- metadata.gz: dc11f265924a159752c9664a53668a7e8e5495693c1b71807017410699587ff1e165256dd574a3a7129924aae440c8227dc9cc0127d7596c726f312839e42577
7
- data.tar.gz: 6f255f61b6c4e5ab6284a94f67df012b356fd1ccbb25f1110b61dba9954a07bde780b8778be8c9574f1c48f82074391fd559b30816d4dffe9de763fa8c28a163
6
+ metadata.gz: 70ba89e8bb29f007a40e51d715306da0cec8ebb9c71331e2f60d08e46005ca12d44eb5e18dace1b531f758b226abe40e1c31f7101d78c95a3864db2410d30c40
7
+ data.tar.gz: 8ffd9db409f9714c7d160d994a19f38d0ffbacd0fb115a77ade48574ba326f73a40b8389a105703386fa524676cfa5b318acc663c37e72d71510f421317f9060
data/.gitignore CHANGED
@@ -6,4 +6,5 @@ pkg/*
6
6
  tmp/*
7
7
  .rbx
8
8
  Gemfile.lock
9
+ .bash_history
9
10
 
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
- while msg = mail_box.deq
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
- if new_thread
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 :task_queue
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 = Queue.new
151
- self.task_queue = Queue.new
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
- should_exit = Thread.current.thread_variable_get(:should_exit) &&
222
- yield_task_queue.empty? &&
223
- pending_io_task_queue.empty? &&
224
- local_task_queue.empty?
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
- task_queue << routine
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
@@ -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
@@ -1,3 +1,3 @@
1
1
  module Rbgo
2
- VERSION = "0.2.8"
2
+ VERSION = "0.2.9"
3
3
  end
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.8
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 00:00:00.000000000 Z
11
+ date: 2019-08-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: system