rbgo 0.2.8 → 0.2.9

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
  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