Skip to content

Commit 741d3ac

Browse files
committed
Adding example of supervision-tree
For now built manually.
1 parent 469eaa3 commit 741d3ac

File tree

2 files changed

+144
-0
lines changed

2 files changed

+144
-0
lines changed

doc/actor/supervision_tree.in.rb

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
require 'concurrent'
2+
3+
logger = Logger.new($stderr) #
4+
Concurrent.configuration.logger = lambda do |level, progname, message = nil, &block|
5+
logger.add level, message, progname, &block
6+
end #
7+
8+
9+
class Master < Concurrent::Actor::RestartingContext
10+
def initialize
11+
# for listener to be child of master
12+
@listener = Listener.spawn(name: 'listener1', supervise: true, args: [self])
13+
end
14+
15+
def on_message(msg)
16+
case msg
17+
when :listener
18+
@listener
19+
when :reset, :terminated, :resumed, :paused
20+
log Logger::DEBUG, " got #{msg} from #{envelope.sender}"
21+
else
22+
pass
23+
end
24+
end
25+
26+
# TODO turn this into Behaviour and make it default part of RestartingContext
27+
def on_event(event)
28+
case event
29+
when :resetting, :restarting
30+
@listener << :terminate!
31+
when Exception, :paused
32+
@listener << :pause!
33+
when :resumed
34+
@listener << :resume!
35+
end
36+
end
37+
end #
38+
39+
class Listener < Concurrent::Actor::RestartingContext
40+
def initialize(master)
41+
@number = (rand() * 100).to_i
42+
end
43+
44+
def on_message(msg)
45+
case msg
46+
when :number
47+
@number
48+
else
49+
pass
50+
end
51+
end
52+
53+
end #
54+
55+
master = Master.spawn(name: 'master', supervise: true)
56+
listener = master.ask!(:listener)
57+
listener.ask!(:number)
58+
59+
master << :crash
60+
61+
sleep 0.1
62+
63+
# ask for listener again, old one is terminated
64+
listener.ask!(:terminated?)
65+
listener = master.ask!(:listener)
66+
listener.ask!(:number)
67+
68+
master.ask!(:terminate!)
69+
70+
sleep 0.1

doc/actor/supervision_tree.out.rb

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
require 'concurrent' # => true
2+
3+
logger = Logger.new($stderr)
4+
Concurrent.configuration.logger = lambda do |level, progname, message = nil, &block|
5+
logger.add level, message, progname, &block
6+
end
7+
8+
9+
class Master < Concurrent::Actor::RestartingContext
10+
def initialize
11+
# for listener to be child of master
12+
@listener = Listener.spawn(name: 'listener1', supervise: true, args: [self])
13+
end
14+
15+
def on_message(msg)
16+
case msg
17+
when :listener
18+
@listener
19+
when :reset, :terminated, :resumed, :paused
20+
log Logger::DEBUG, " got #{msg} from #{envelope.sender}"
21+
else
22+
pass
23+
end
24+
end
25+
26+
# TODO turn this into Behaviour and make it default part of RestartingContext
27+
def on_event(event)
28+
case event
29+
when :resetting, :restarting
30+
@listener << :terminate!
31+
when Exception, :paused
32+
@listener << :pause!
33+
when :resumed
34+
@listener << :resume!
35+
end
36+
end
37+
end
38+
39+
class Listener < Concurrent::Actor::RestartingContext
40+
def initialize(master)
41+
@number = (rand() * 100).to_i
42+
end
43+
44+
def on_message(msg)
45+
case msg
46+
when :number
47+
@number
48+
else
49+
pass
50+
end
51+
end
52+
53+
end
54+
55+
master = Master.spawn(name: 'master', supervise: true)
56+
# => #<Concurrent::Actor::Reference:0x7fbe491a71b0 /master (Master)>
57+
listener = master.ask!(:listener)
58+
# => #<Concurrent::Actor::Reference:0x7fbe4919ceb8 /master/listener1 (Listener)>
59+
listener.ask!(:number) # => 92
60+
61+
master << :crash
62+
# => #<Concurrent::Actor::Reference:0x7fbe491a71b0 /master (Master)>
63+
64+
sleep 0.1 # => 0
65+
66+
# ask for listener again, old one is terminated
67+
listener.ask!(:terminated?) # => true
68+
listener = master.ask!(:listener)
69+
# => #<Concurrent::Actor::Reference:0x7fbe49175bd8 /master/listener1 (Listener)>
70+
listener.ask!(:number) # => 99
71+
72+
master.ask!(:terminate!) # => true
73+
74+
sleep 0.1 # => 0

0 commit comments

Comments
 (0)