Skip to content

Commit dc659fe

Browse files
committed
Redefined actor reset behavior.
1 parent 115309f commit dc659fe

File tree

4 files changed

+35
-33
lines changed

4 files changed

+35
-33
lines changed

lib/concurrent/actor/actor_context.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ module Concurrent
3434
# @see http://akka.io/
3535
# @see http://www.erlang.org/doc/getting_started/conc_prog.html
3636
# @see http://www.scala-lang.org/api/current/index.html#scala.actors.Actor
37+
#
38+
# @see http://doc.akka.io/docs/akka/snapshot/general/supervision.html#What_Restarting_Means What Restarting Means
39+
# @see http://doc.akka.io/docs/akka/snapshot/general/supervision.html#What_Lifecycle_Monitoring_Means What Lifecycle Monitoring Means
3740
module ActorContext
3841

3942
# Callback method called by the `ActorRef` which encapsulates the actor instance.

lib/concurrent/actor/simple_actor_ref.rb

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,9 @@ def initialize(actor, opts = {})
1313
@mutex = Mutex.new
1414
@executor = SingleThreadExecutor.new
1515
@stop_event = Event.new
16-
@reset_on_error = opts.fetch(:reset_on_error, true)
16+
@reset_on_error = opts.fetch(:reset_on_error, false)
1717
@exception_class = opts.fetch(:rescue_exception, false) ? Exception : StandardError
18+
@args = opts.fetch(:args, {})
1819
self.observers = CopyOnNotifyObserverSet.new
1920

2021
@actor.define_singleton_method(:shutdown, &method(:set_stop_event))
@@ -76,7 +77,9 @@ def process_message(message)
7677
result = @actor.receive(*message.payload)
7778
rescue @exception_class => ex
7879
@actor.on_error(Time.now, message.payload, ex)
79-
@actor.on_reset if @reset_on_error
80+
if @reset_on_error
81+
@mutex.synchronize{ @actor = @actor.class.new(*@args) }
82+
end
8083
ensure
8184
now = Time.now
8285
message.ivar.complete(ex.nil?, result, ex)

spec/concurrent/actor/actor_ref_shared.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
require 'spec_helper'
22

3-
def shared_actor_test_class
3+
def create_actor_test_class
44
Class.new do
55
include Concurrent::ActorContext
66

spec/concurrent/actor/simple_actor_ref_spec.rb

Lines changed: 26 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -11,21 +11,21 @@ module Concurrent
1111
end
1212

1313
subject do
14-
shared_actor_test_class.spawn
14+
create_actor_test_class.spawn
1515
end
1616

1717
it_should_behave_like :actor_ref
1818

1919
context 'construction' do
2020

2121
it 'supports :args being nil' do
22-
subject = shared_actor_test_class.spawn
22+
subject = create_actor_test_class.spawn
2323
actor = subject.instance_variable_get(:@actor)
2424
actor.argv.should be_empty
2525
end
2626

2727
it 'passes all :args option to the actor constructor' do
28-
subject = shared_actor_test_class.spawn(args: [1, 2, 3, 4])
28+
subject = create_actor_test_class.spawn(args: [1, 2, 3, 4])
2929
actor = subject.instance_variable_get(:@actor)
3030
actor.argv.should eq [1, 2, 3, 4]
3131
end
@@ -34,44 +34,40 @@ module Concurrent
3434
subject # prevent the after(:all) block from breaking this test
3535
opts = {foo: :bar, hello: :world}
3636
described_class.should_receive(:new).once.with(anything, opts)
37-
shared_actor_test_class.spawn(opts)
37+
create_actor_test_class.spawn(opts)
3838
end
3939

4040
it 'calls #on_start on the actor' do
41-
actor = double(:shared_actor_test_class)
41+
actor = double(:create_actor_test_class)
4242
actor.should_receive(:on_start).once.with(no_args)
4343
SimpleActorRef.new(actor)
4444
end
4545
end
4646

4747
context 'reset_on_error' do
4848

49-
after(:each) do
50-
@ref.shutdown if @ref
51-
end
52-
53-
it 'causes #on_reset to be called on exception when true' do
54-
@ref = shared_actor_test_class.spawn(reset_on_error: true)
55-
actor = @ref.instance_variable_get(:@actor)
56-
actor.should_receive(:on_reset).once.with(no_args)
57-
@ref << :poison
58-
sleep(0.1)
49+
it 'creates a new actor on exception when true' do
50+
clazz = create_actor_test_class
51+
args = [:foo, :bar, :hello, :world]
52+
ref = clazz.spawn(reset_on_error: true, args: args)
53+
clazz.should_receive(:new).once.with(*args)
54+
ref.post(:poison)
5955
end
6056

61-
it 'prevents #on_reset form being called on exception when false' do
62-
@ref = shared_actor_test_class.spawn(reset_on_error: false)
63-
actor = @ref.instance_variable_get(:@actor)
64-
actor.should_not_receive(:on_reset).with(any_args)
65-
@ref << :poison
66-
sleep(0.1)
57+
it 'does not create a new actor on exception when false' do
58+
clazz = create_actor_test_class
59+
args = [:foo, :bar, :hello, :world]
60+
ref = clazz.spawn(reset_on_error: true, args: args)
61+
clazz.should_not_receive(:new).with(any_args)
62+
ref.post(:poison)
6763
end
6864

69-
it 'defaults to true' do
70-
@ref = shared_actor_test_class.spawn
71-
actor = @ref.instance_variable_get(:@actor)
72-
actor.should_receive(:on_reset).once.with(no_args)
73-
@ref << :poison
74-
sleep(0.1)
65+
it 'defaults to false' do
66+
clazz = create_actor_test_class
67+
args = [:foo, :bar, :hello, :world]
68+
ref = clazz.spawn(args: args)
69+
clazz.should_not_receive(:new).with(any_args)
70+
ref.post(:poison)
7571
end
7672
end
7773

@@ -82,7 +78,7 @@ module Concurrent
8278
end
8379

8480
it 'rescues Exception in the actor thread when true' do
85-
@ref = shared_actor_test_class.spawn(
81+
@ref = create_actor_test_class.spawn(
8682
abort_on_exception: false,
8783
rescue_exception: true
8884
)
@@ -97,7 +93,7 @@ module Concurrent
9793
end
9894

9995
it 'rescues StandardError in the actor thread when false' do
100-
@ref = shared_actor_test_class.spawn(
96+
@ref = create_actor_test_class.spawn(
10197
abort_on_exception: false,
10298
rescue_exception: false
10399
)
@@ -112,7 +108,7 @@ module Concurrent
112108
end
113109

114110
it 'defaults to false' do
115-
@ref = shared_actor_test_class.spawn(abort_on_exception: false)
111+
@ref = create_actor_test_class.spawn(abort_on_exception: false)
116112

117113
ivar = @ref.post(:poison)
118114
sleep(0.1)

0 commit comments

Comments
 (0)