rbgo 0.2.15 → 0.3.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 +4 -4
- data/README.md +30 -1
- data/lib/rbgo/actor.rb +143 -8
- data/lib/rbgo/corun.rb +5 -2
- data/lib/rbgo/io_machine.rb +24 -12
- data/lib/rbgo/network_service.rb +8 -4
- data/lib/rbgo/select_chan.rb +2 -1
- 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: 97e2bc03c10cecfd43a53f1b5a322bb834ba96585db1d604efc7fb13ac3f3728
|
4
|
+
data.tar.gz: a32cbd76dca6ade5900239d6168034e9678193eac871f98fc4a0d28a5bc025c3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ace96944fbbd9437ade60d4540eb1fdc4b277445eaff47fa11d5176202ae986f6f58b0e5c15c3e4cfd3e40d92c01e074b03d54a6e94d39249a4332bb7a962cfe
|
7
|
+
data.tar.gz: 578f17172ef9fddaf97244b1cb5e49b22f1ac0e4730e7c1c02753fde9d356b4038809eb3bf12dfd11cc3e82505543dda6c3c8e81ff656807bfdd56eafab6a163
|
data/README.md
CHANGED
@@ -119,7 +119,36 @@ actor = Rbgo::Actor.new do|msg, actor|
|
|
119
119
|
end
|
120
120
|
end
|
121
121
|
|
122
|
-
actor.send_msg :msg1 #won't block
|
122
|
+
actor.send_msg :msg1 #won't block
|
123
|
+
|
124
|
+
# Actors can be parent-child relationship, and can be linked or monitored
|
125
|
+
|
126
|
+
supervisor = Rbgo::Actor.new do |msg, actor|
|
127
|
+
case msg
|
128
|
+
when Rbgo::ActorClosedMsg
|
129
|
+
p msg.actor.close_reason # why actor closed
|
130
|
+
actor.spawn_monitor(&msg.actor.handler) # spawn again
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
10000.times do
|
135
|
+
supervisor.spawn_monitor do |msg, _| # when these actors closed, supervisor will receive ActorClosedMsg
|
136
|
+
# and decide what to do
|
137
|
+
p msg
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
link1 = Rbgo::Actor.new do |msg, actor|
|
142
|
+
end
|
143
|
+
link2 = link1.spawn_link do
|
144
|
+
end
|
145
|
+
|
146
|
+
link1.close # any one of linked actors close will cause all other close
|
147
|
+
|
148
|
+
# link / unlink
|
149
|
+
# monitor / demonitor
|
150
|
+
# when use spawn_xx , actors have parent-child relationship
|
151
|
+
|
123
152
|
|
124
153
|
# TaskList do task in order but do it asynchronously, task may be executed in different thread
|
125
154
|
|
data/lib/rbgo/actor.rb
CHANGED
@@ -1,38 +1,171 @@
|
|
1
1
|
require 'thread'
|
2
2
|
require_relative 'once'
|
3
|
+
require_relative 'synchronized_collection'
|
4
|
+
require_relative 'reentrant_mutex'
|
3
5
|
|
4
6
|
module Rbgo
|
7
|
+
class ActorClosedMsg
|
8
|
+
attr_accessor :actor
|
9
|
+
|
10
|
+
def initialize(actor)
|
11
|
+
self.actor = actor
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
5
15
|
class Actor
|
6
16
|
private
|
7
17
|
|
8
|
-
attr_accessor :mail_box, :once_for_msg_loop
|
18
|
+
attr_accessor :mail_box, :once_for_msg_loop, :once_for_close,
|
19
|
+
:close_mutex, :parent, :children, :linked_actors, :supervisor_actors
|
9
20
|
|
10
21
|
public
|
11
22
|
|
12
23
|
attr_accessor :handler
|
24
|
+
attr_reader :close_reason
|
13
25
|
|
14
26
|
def initialize(&handler)
|
15
27
|
self.handler = handler
|
28
|
+
@close_reason = nil
|
16
29
|
self.mail_box = Queue.new
|
17
30
|
self.once_for_msg_loop = Once.new
|
31
|
+
self.once_for_close = Once.new
|
32
|
+
self.close_mutex = ReentrantMutex.new
|
33
|
+
|
34
|
+
self.children = SyncSet.new
|
35
|
+
self.linked_actors = SyncSet.new
|
36
|
+
self.supervisor_actors = SyncSet.new
|
18
37
|
end
|
19
38
|
|
20
39
|
def send_msg(msg)
|
21
40
|
mail_box << msg
|
22
41
|
start_msg_loop
|
23
|
-
|
42
|
+
self
|
24
43
|
end
|
25
44
|
|
26
|
-
def
|
27
|
-
|
28
|
-
|
29
|
-
|
45
|
+
def send_children(msg)
|
46
|
+
children.each do |child|
|
47
|
+
child.send_msg(msg) rescue nil
|
48
|
+
end
|
49
|
+
self
|
50
|
+
end
|
51
|
+
|
52
|
+
def close(reason = nil)
|
53
|
+
once_for_close.do do
|
54
|
+
close_mutex.synchronize do
|
55
|
+
@close_reason = reason
|
56
|
+
mail_box.close
|
57
|
+
mail_box.clear
|
58
|
+
|
59
|
+
(parent&.send :children)&.delete(self)
|
60
|
+
self.parent = nil
|
61
|
+
self.children = nil
|
62
|
+
|
63
|
+
linked_actors.each do |l|
|
64
|
+
CoRun::Routine.new(new_thread: false, queue_tag: :default) do
|
65
|
+
l.close
|
66
|
+
end
|
67
|
+
end
|
68
|
+
self.linked_actors = nil
|
69
|
+
|
70
|
+
supervisor_actors.each do |sup|
|
71
|
+
sup.send_msg(ActorClosedMsg.new(self)) rescue nil
|
72
|
+
end
|
73
|
+
self.supervisor_actors = nil
|
74
|
+
|
75
|
+
nil
|
76
|
+
end
|
77
|
+
end
|
30
78
|
end
|
31
79
|
|
32
80
|
def closed?
|
33
81
|
mail_box.closed?
|
34
82
|
end
|
35
83
|
|
84
|
+
def spawn_child(&handler)
|
85
|
+
close_mutex.synchronize do
|
86
|
+
raise "can not spawn from a closed actor" if closed?
|
87
|
+
child = Actor.new(&handler)
|
88
|
+
child.send :parent=, self
|
89
|
+
children.add(child)
|
90
|
+
child
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def spawn_link(&handler)
|
95
|
+
close_mutex.synchronize do
|
96
|
+
raise "can not spawn from a closed actor" if closed?
|
97
|
+
l = spawn_child(&handler)
|
98
|
+
l.send(:linked_actors).add(self)
|
99
|
+
linked_actors.add(l)
|
100
|
+
l
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def link(actor)
|
105
|
+
return self if self.equal?(actor)
|
106
|
+
close_mutex.synchronize do
|
107
|
+
raise "can not link from a closed actor" if closed?
|
108
|
+
actor.send(:close_mutex).synchronize do
|
109
|
+
if actor.closed?
|
110
|
+
close
|
111
|
+
else
|
112
|
+
actor.send(:linked_actors).add(self)
|
113
|
+
linked_actors.add(actor)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
self
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
def unlink(actor)
|
121
|
+
return self if self.equal?(actor)
|
122
|
+
close_mutex.synchronize do
|
123
|
+
raise "can not unlink from a closed actor" if closed?
|
124
|
+
actor.send(:close_mutex).synchronize do
|
125
|
+
unless actor.closed?
|
126
|
+
actor.send(:linked_actors).delete(self)
|
127
|
+
end
|
128
|
+
linked_actors.delete(actor)
|
129
|
+
end
|
130
|
+
self
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
def spawn_monitor(&handler)
|
135
|
+
close_mutex.synchronize do
|
136
|
+
raise "can not spawn from a closed actor" if closed?
|
137
|
+
m = spawn_child(&handler)
|
138
|
+
m.send(:supervisor_actors).add(self)
|
139
|
+
m
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
def monitor(actor)
|
144
|
+
return self if self.equal?(actor)
|
145
|
+
close_mutex.synchronize do
|
146
|
+
raise "can not monitor from a closed actor" if closed?
|
147
|
+
actor.send(:close_mutex).synchronize do
|
148
|
+
if actor.closed?
|
149
|
+
send_msg(ActorClosedMsg.new(actor))
|
150
|
+
else
|
151
|
+
actor.send(:supervisor_actors).add(self)
|
152
|
+
end
|
153
|
+
end
|
154
|
+
self
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
def demonitor(actor)
|
159
|
+
return self if self.equal?(actor)
|
160
|
+
close_mutex.synchronize do
|
161
|
+
raise "can not demonitor from a closed actor" if closed?
|
162
|
+
actor.send(:close_mutex).synchronize do
|
163
|
+
actor.send(:supervisor_actors)&.delete(self)
|
164
|
+
end
|
165
|
+
self
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
36
169
|
private
|
37
170
|
|
38
171
|
def start_msg_loop
|
@@ -43,7 +176,7 @@ module Rbgo
|
|
43
176
|
msg = mail_box.deq(true)
|
44
177
|
rescue ThreadError
|
45
178
|
self.once_for_msg_loop = Once.new
|
46
|
-
start_msg_loop unless mail_box.empty?
|
179
|
+
start_msg_loop unless (mail_box.empty? || mail_box.closed?)
|
47
180
|
break
|
48
181
|
else
|
49
182
|
call_handler(msg)
|
@@ -57,7 +190,9 @@ module Rbgo
|
|
57
190
|
def call_handler(msg)
|
58
191
|
handler.call(msg, self) if handler
|
59
192
|
rescue Exception => ex
|
60
|
-
|
193
|
+
close(ex)
|
194
|
+
STDERR.puts(ex.message)
|
195
|
+
STDERR.puts(ex.backtrace)
|
61
196
|
end
|
62
197
|
end
|
63
198
|
end
|
data/lib/rbgo/corun.rb
CHANGED
@@ -117,6 +117,7 @@ module Rbgo
|
|
117
117
|
attr_accessor :args, :blk, :fiber, :io_receipt
|
118
118
|
|
119
119
|
def initialize(*args, new_thread: false, queue_tag: :default, &blk) # :default :none :actor
|
120
|
+
raise 'Routine must have a block' if blk.nil?
|
120
121
|
self.args = args
|
121
122
|
self.blk = blk
|
122
123
|
Scheduler.instance.schedule(self, new_thread: new_thread, queue_tag: queue_tag)
|
@@ -244,7 +245,8 @@ module Rbgo
|
|
244
245
|
task.send :perform
|
245
246
|
rescue Exception => ex
|
246
247
|
task.error = ex
|
247
|
-
STDERR.puts(ex)
|
248
|
+
STDERR.puts(ex.message)
|
249
|
+
STDERR.puts(ex.backtrace)
|
248
250
|
next
|
249
251
|
ensure
|
250
252
|
Thread.current.thread_variable_set(:performing, false)
|
@@ -271,7 +273,8 @@ module Rbgo
|
|
271
273
|
end
|
272
274
|
end
|
273
275
|
rescue Exception => ex
|
274
|
-
STDERR.puts
|
276
|
+
STDERR.puts(ex.message)
|
277
|
+
STDERR.puts(ex.backtrace)
|
275
278
|
end
|
276
279
|
nil
|
277
280
|
end
|
data/lib/rbgo/io_machine.rb
CHANGED
@@ -194,7 +194,8 @@ module Rbgo
|
|
194
194
|
buf = io.recv_nonblock(maxlen, flags, exception: false)
|
195
195
|
rescue Exception => ex
|
196
196
|
notify_blk.call
|
197
|
-
STDERR.puts
|
197
|
+
STDERR.puts(ex.message)
|
198
|
+
STDERR.puts(ex.backtrace)
|
198
199
|
throw :exit
|
199
200
|
end
|
200
201
|
if buf == :wait_readable
|
@@ -243,7 +244,8 @@ module Rbgo
|
|
243
244
|
buf = sock.recvmsg_nonblock(nil, flags, maxcontrollen, opts.merge(exception: false))
|
244
245
|
rescue Exception => ex
|
245
246
|
notify_blk.call
|
246
|
-
STDERR.puts
|
247
|
+
STDERR.puts(ex.message)
|
248
|
+
STDERR.puts(ex.backtrace)
|
247
249
|
break
|
248
250
|
end
|
249
251
|
if buf == :wait_readable
|
@@ -272,7 +274,8 @@ module Rbgo
|
|
272
274
|
buf = sock.recvmsg_nonblock(need_read_bytes_n, flags, maxcontrollen, opts.merge(exception: false))
|
273
275
|
rescue Exception => ex
|
274
276
|
notify_blk.call
|
275
|
-
STDERR.puts
|
277
|
+
STDERR.puts(ex.message)
|
278
|
+
STDERR.puts(ex.backtrace)
|
276
279
|
break
|
277
280
|
end
|
278
281
|
if buf == :wait_readable
|
@@ -322,7 +325,8 @@ module Rbgo
|
|
322
325
|
monitor.close
|
323
326
|
receipt.res = bytes_written_n
|
324
327
|
receipt.notify
|
325
|
-
STDERR.puts
|
328
|
+
STDERR.puts(ex.message)
|
329
|
+
STDERR.puts(ex.backtrace)
|
326
330
|
break
|
327
331
|
end
|
328
332
|
if n == :wait_writable
|
@@ -357,7 +361,8 @@ module Rbgo
|
|
357
361
|
res = sock.connect_nonblock(remote_sockaddr, exception: false)
|
358
362
|
rescue Exception => ex
|
359
363
|
notify_blk.call
|
360
|
-
STDERR.puts
|
364
|
+
STDERR.puts(ex.message)
|
365
|
+
STDERR.puts(ex.backtrace)
|
361
366
|
throw :exit
|
362
367
|
end
|
363
368
|
if res == :wait_writable
|
@@ -391,7 +396,8 @@ module Rbgo
|
|
391
396
|
res = sock.accept_nonblock(exception: false)
|
392
397
|
rescue Exception => ex
|
393
398
|
notify_blk.call
|
394
|
-
STDERR.puts
|
399
|
+
STDERR.puts(ex.message)
|
400
|
+
STDERR.puts(ex.backtrace)
|
395
401
|
throw :exit
|
396
402
|
end
|
397
403
|
if res == :wait_readable
|
@@ -425,7 +431,8 @@ module Rbgo
|
|
425
431
|
buf = io.read_nonblock(maxlen, exception: false)
|
426
432
|
rescue Exception => ex
|
427
433
|
notify_blk.call
|
428
|
-
STDERR.puts
|
434
|
+
STDERR.puts(ex.message)
|
435
|
+
STDERR.puts(ex.backtrace)
|
429
436
|
throw :exit
|
430
437
|
end
|
431
438
|
if buf == :wait_readable
|
@@ -481,7 +488,8 @@ module Rbgo
|
|
481
488
|
end
|
482
489
|
rescue Exception => ex
|
483
490
|
notify_blk.call
|
484
|
-
STDERR.puts
|
491
|
+
STDERR.puts(ex.message)
|
492
|
+
STDERR.puts(ex.backtrace)
|
485
493
|
break
|
486
494
|
end
|
487
495
|
if buf == :wait_readable
|
@@ -531,7 +539,8 @@ module Rbgo
|
|
531
539
|
end
|
532
540
|
rescue Exception => ex
|
533
541
|
notify_blk.call
|
534
|
-
STDERR.puts
|
542
|
+
STDERR.puts(ex.message)
|
543
|
+
STDERR.puts(ex.backtrace)
|
535
544
|
break
|
536
545
|
end
|
537
546
|
if buf == :wait_readable
|
@@ -592,7 +601,8 @@ module Rbgo
|
|
592
601
|
buf = io.read_nonblock(buf_size, exception: false)
|
593
602
|
rescue Exception => ex
|
594
603
|
notify_blk.call
|
595
|
-
STDERR.puts
|
604
|
+
STDERR.puts(ex.message)
|
605
|
+
STDERR.puts(ex.backtrace)
|
596
606
|
break
|
597
607
|
end
|
598
608
|
if buf == :wait_readable
|
@@ -618,7 +628,8 @@ module Rbgo
|
|
618
628
|
buf = io.read_nonblock(need_read_bytes_n, exception: false)
|
619
629
|
rescue Exception => ex
|
620
630
|
notify_blk.call
|
621
|
-
STDERR.puts
|
631
|
+
STDERR.puts(ex.message)
|
632
|
+
STDERR.puts(ex.backtrace)
|
622
633
|
break
|
623
634
|
end
|
624
635
|
if buf == :wait_readable
|
@@ -664,7 +675,8 @@ module Rbgo
|
|
664
675
|
monitor.close
|
665
676
|
receipt.res = bytes_written_n
|
666
677
|
receipt.notify
|
667
|
-
STDERR.puts
|
678
|
+
STDERR.puts(ex.message)
|
679
|
+
STDERR.puts(ex.backtrace)
|
668
680
|
end
|
669
681
|
end
|
670
682
|
monitor.value[1].call
|
data/lib/rbgo/network_service.rb
CHANGED
@@ -65,12 +65,14 @@ module Rbgo
|
|
65
65
|
end
|
66
66
|
end
|
67
67
|
rescue Exception => ex
|
68
|
-
STDERR.puts
|
68
|
+
STDERR.puts(ex.message)
|
69
|
+
STDERR.puts(ex.backtrace)
|
69
70
|
end
|
70
71
|
end
|
71
72
|
rescue Exception => ex
|
72
73
|
res_chan << service
|
73
|
-
STDERR.puts
|
74
|
+
STDERR.puts(ex.message)
|
75
|
+
STDERR.puts(ex.backtrace)
|
74
76
|
end
|
75
77
|
end
|
76
78
|
service.send :service_routine=, routine
|
@@ -100,12 +102,14 @@ module Rbgo
|
|
100
102
|
end
|
101
103
|
end
|
102
104
|
rescue Exception => ex
|
103
|
-
STDERR.puts
|
105
|
+
STDERR.puts(ex.message)
|
106
|
+
STDERR.puts(ex.backtrace)
|
104
107
|
end
|
105
108
|
end
|
106
109
|
rescue Exception => ex
|
107
110
|
res_chan << service
|
108
|
-
STDERR.puts
|
111
|
+
STDERR.puts(ex.message)
|
112
|
+
STDERR.puts(ex.backtrace)
|
109
113
|
end
|
110
114
|
end
|
111
115
|
service.send :service_routine=, routine
|
data/lib/rbgo/select_chan.rb
CHANGED
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.
|
4
|
+
version: 0.3.0
|
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-09-
|
11
|
+
date: 2019-09-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: system
|