Skip to content

Commit 0ec8e08

Browse files
committed
Configurable Core
executor can be configured, other options will follow spawn can be also called with hash instead of class, name, *args
1 parent b399efe commit 0ec8e08

File tree

4 files changed

+70
-43
lines changed

4 files changed

+70
-43
lines changed

lib/concurrent/actress.rb

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -40,25 +40,38 @@ class Root
4040
def on_message(message)
4141
case message.first
4242
when :spawn
43-
spawn *message[1..2], *message[3], &message[4]
43+
spawn message[1], &message[2]
4444
else
4545
# ignore
4646
end
4747
end
4848
end
4949

5050
# A root actor, a default parent of all actors spawned outside an actor
51-
ROOT = Core.new(nil, '/', Root).reference
51+
ROOT = Core.new(parent: nil, name: '/', class: Root).reference
5252

53-
# @param [Context] actress_class to be spawned
54-
# @param [String, Symbol] name of the instance, it's used to generate the path of the actor
55-
# @param args for actress_class instantiation
5653
# @param block for actress_class instantiation
57-
def self.spawn(actress_class, name, *args, &block)
54+
def self.spawn(*args, &block)
5855
if Actress.current
59-
Core.new(Actress.current, name, actress_class, *args, &block).reference
56+
Core.new(spawn_optionify(*args).merge(parent: Actress.current), &block).reference
6057
else
61-
ROOT.ask([:spawn, actress_class, name, args, block]).value
58+
ROOT.ask([:spawn, spawn_optionify(*args), block]).value
59+
end
60+
end
61+
62+
# @overload spawn_optionify(actress_class, name, *args)
63+
# @param [Context] actress_class to be spawned
64+
# @param [String, Symbol] name of the instance, it's used to generate the path of the actor
65+
# @param args for actress_class instantiation
66+
# @overload spawn_optionify(opts)
67+
# see {Core.new} opts
68+
def self.spawn_optionify(*args)
69+
if args.size == 1 && args.first.is_a?(Hash)
70+
args.first
71+
else
72+
{ class: args[0],
73+
name: args[1],
74+
args: args[2..-1] }
6275
end
6376
end
6477
end

lib/concurrent/actress/context.rb

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ def on_envelope(envelope)
3737
end
3838

3939
# @see Actress.spawn
40-
def spawn(actress_class, name, *args, &block)
41-
Actress.spawn(actress_class, name, *args, &block)
40+
def spawn(*args, &block)
41+
Actress.spawn(*args, &block)
4242
end
4343

4444
# @see Core#children
@@ -70,8 +70,13 @@ def self.included(base)
7070

7171
module ClassMethods
7272
# behaves as {Actress.spawn} but class_name is omitted
73-
def spawn(name, *args, &block)
74-
Actress.spawn self, name, *args, &block
73+
def spawn(name_or_opts, *args, &block)
74+
opts = if name_or_opts.is_a? Hash
75+
name_or_opts.merge class: self
76+
else
77+
{ class: self, name: name_or_opts, args: args }
78+
end
79+
Actress.spawn opts, &block
7580
end
7681
end
7782
end

lib/concurrent/actress/core.rb

Lines changed: 29 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -9,28 +9,37 @@ class Core
99
attr_reader :reference, :name, :path, :logger, :parent_core
1010
private :parent_core
1111

12-
# @param [Reference, nil] parent of an actor spawning this one
13-
# @param [String] name
14-
# @param [Context] actress_class a class to be instantiated defining Actor's behaviour
15-
# @param args arguments for actress_class instantiation
16-
# @param block for actress_class instantiation
17-
def initialize(parent, name, actress_class, *args, &block)
18-
@mailbox = Array.new
19-
@one_by_one = OneByOne.new
20-
@executor = Concurrent.configuration.global_task_pool # TODO make configurable
21-
@parent_core = (Type! parent, Reference, NilClass) && parent.send(:core)
22-
@name = (Type! name, String, Symbol).to_s
23-
@children = []
12+
# @option opts [String] name
13+
# @option opts [Reference, nil] parent of an actor spawning this one
14+
# @option opts [Context] actress_class a class to be instantiated defining Actor's behaviour
15+
# @option opts [Array<Object>] args arguments for actress_class instantiation
16+
# @option opts [Executor] executor, default is `Concurrent.configuration.global_task_pool`
17+
# @param [Proc] block for class instantiation
18+
def initialize(opts = {}, &block)
19+
@mailbox = Array.new
20+
@one_by_one = OneByOne.new
21+
# noinspection RubyArgCount
22+
@terminated = Event.new
23+
@executor = Type! opts.fetch(:executor, Concurrent.configuration.global_task_pool), Executor
24+
@children = []
25+
@reference = Reference.new self
26+
@name = (Type! opts.fetch(:name), String, Symbol).to_s
27+
28+
parent = opts[:parent]
29+
@parent_core = (Type! parent, Reference, NilClass) && parent.send(:core)
30+
if @parent_core.nil? && @name != '/'
31+
raise 'only root has no parent'
32+
end
33+
2434
@path = @parent_core ? File.join(@parent_core.path, @name) : @name
2535
@logger = Logger.new($stderr) # TODO add proper logging
2636
@logger.progname = @path
27-
@reference = Reference.new self
28-
# noinspection RubyArgCount
29-
@terminated = Event.new
3037

31-
parent_core.add_child reference if parent_core
38+
@parent_core.add_child reference if @parent_core
39+
40+
@actress_class = actress_class = Child! opts.fetch(:class), Context
41+
args = opts.fetch(:args, [])
3242

33-
@actress_class = Child! actress_class, Context
3443
schedule_execution do
3544
begin
3645
@actress = actress_class.new *args, &block
@@ -42,9 +51,9 @@ def initialize(parent, name, actress_class, *args, &block)
4251
end
4352
end
4453

45-
# @return [Reference] of parent actor
54+
# @return [Reference, nil] of parent actor
4655
def parent
47-
@parent_core.reference
56+
@parent_core && @parent_core.reference
4857
end
4958

5059
# @return [Array<Reference>] of children actors
@@ -155,7 +164,7 @@ def schedule_execution
155164
Thread.current[:__current_actress__] = reference
156165
yield
157166
rescue => e
158-
logger.error e
167+
logger.fatal e
159168
ensure
160169
Thread.current[:__current_actress__] = nil
161170
end

spec/actress.rb

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -36,18 +36,19 @@ def on_message(message)
3636

3737
def assert condition
3838
unless condition
39-
require 'pry'
40-
binding.pry
39+
# require 'pry'
40+
# binding.pry
4141
raise
42+
puts "--- \n#{caller.join("\n")}"
4243
end
4344
end
4445

4546

46-
Array.new(100).map do
47-
Thread.new do
48-
20.times do |i|
49-
# it format('--- %3d ---', i) do
50-
puts format('--- %3d ---', i)
47+
# it format('--- %3d ---', i) do
48+
10.times do |i|
49+
puts format('--- %3d ---', i)
50+
Array.new(10).map do
51+
Thread.new do
5152
# trace! do
5253
queue = Queue.new
5354
actor = Ping.spawn :ping, queue
@@ -71,8 +72,7 @@ def assert condition
7172
actor << :terminate
7273
assert actor.ask(:blow_up).wait.rejected?
7374
end
74-
end
75-
end.each(&:join)
76-
77-
# end
75+
end.each(&:join)
76+
end
77+
# end
7878
# end

0 commit comments

Comments
 (0)