concurrent-ruby 0.6.0 → 0.6.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/{LICENSE → LICENSE.txt} +0 -0
- data/README.md +55 -51
- data/lib/concurrent/actress.rb +152 -6
- data/lib/concurrent/actress/ad_hoc.rb +6 -0
- data/lib/concurrent/actress/context.rb +10 -8
- data/lib/concurrent/actress/core.rb +44 -20
- data/lib/concurrent/actress/core_delegations.rb +5 -0
- data/lib/concurrent/actress/envelope.rb +21 -5
- data/lib/concurrent/actress/reference.rb +5 -5
- data/lib/concurrent/agent.rb +9 -9
- data/lib/concurrent/configuration.rb +7 -2
- data/lib/concurrent/executor/ruby_thread_pool_executor.rb +0 -1
- data/lib/concurrent/executor/{one_by_one.rb → serialized_execution.rb} +21 -8
- data/lib/concurrent/executor/timer_set.rb +6 -1
- data/lib/concurrent/executors.rb +1 -1
- data/lib/concurrent/logging.rb +1 -1
- data/lib/concurrent/observable.rb +1 -1
- data/lib/concurrent/version.rb +1 -1
- data/spec/concurrent/actress_spec.rb +84 -64
- data/spec/concurrent/agent_spec.rb +2 -2
- data/spec/concurrent/configuration_spec.rb +0 -2
- data/spec/concurrent/executor/thread_pool_shared.rb +30 -0
- data/spec/concurrent/scheduled_task_spec.rb +2 -4
- data/spec/concurrent/supervisor_spec.rb +2 -1
- data/spec/concurrent/timer_task_spec.rb +0 -2
- data/spec/spec_helper.rb +10 -0
- data/spec/support/example_group_extensions.rb +14 -10
- metadata +5 -6
- data/lib/concurrent/actress/doc.md +0 -53
@@ -20,7 +20,7 @@ module Concurrent
|
|
20
20
|
end
|
21
21
|
|
22
22
|
context '#send_off' do
|
23
|
-
subject { Agent.new 2 }
|
23
|
+
subject { Agent.new 2, executor: executor }
|
24
24
|
|
25
25
|
it 'executes post and post-off in order' do
|
26
26
|
subject.post { |v| v + 2 }
|
@@ -164,7 +164,7 @@ module Concurrent
|
|
164
164
|
subject.post { nil }
|
165
165
|
sleep(0.1)
|
166
166
|
subject.
|
167
|
-
instance_variable_get(:@
|
167
|
+
instance_variable_get(:@serialized_execution).
|
168
168
|
instance_variable_get(:@stash).
|
169
169
|
size.should eq 2
|
170
170
|
end
|
@@ -100,6 +100,36 @@ share_examples_for :executor_service do
|
|
100
100
|
end
|
101
101
|
end
|
102
102
|
|
103
|
+
context '#shutdown followed by #wait_for_termination' do
|
104
|
+
it "allows in-progress tasks to complete" do
|
105
|
+
@expected = false
|
106
|
+
subject.post{ sleep 0.1; @expected = true }
|
107
|
+
subject.shutdown
|
108
|
+
subject.wait_for_termination(1)
|
109
|
+
@expected.should be_true
|
110
|
+
end
|
111
|
+
|
112
|
+
it 'allows pending tasks to complete' do
|
113
|
+
@expected = false
|
114
|
+
subject.post{ sleep(0.1) }
|
115
|
+
subject.post{ sleep(0.1); @expected = true }
|
116
|
+
subject.shutdown
|
117
|
+
subject.wait_for_termination(1)
|
118
|
+
@expected.should be_true
|
119
|
+
end
|
120
|
+
|
121
|
+
it "stops accepting/running new tasks" do
|
122
|
+
@expected = :start
|
123
|
+
subject.post{ sleep(0.1) }
|
124
|
+
subject.post{ sleep(0.1); @expected = :should_be_run }
|
125
|
+
subject.shutdown
|
126
|
+
subject.post{ @expected = :should_not_be_run }
|
127
|
+
subject.wait_for_termination(1)
|
128
|
+
@expected.should == :should_be_run
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
|
103
133
|
context '#kill' do
|
104
134
|
|
105
135
|
it 'stops accepting new tasks' do
|
@@ -7,8 +7,6 @@ require_relative 'observable_shared'
|
|
7
7
|
module Concurrent
|
8
8
|
|
9
9
|
describe ScheduledTask do
|
10
|
-
with_full_reset
|
11
|
-
|
12
10
|
context 'behavior' do
|
13
11
|
|
14
12
|
# obligation
|
@@ -56,9 +54,9 @@ module Concurrent
|
|
56
54
|
it_should_behave_like :dereferenceable
|
57
55
|
|
58
56
|
# observable
|
59
|
-
|
57
|
+
|
60
58
|
subject{ ScheduledTask.new(0.1){ nil } }
|
61
|
-
|
59
|
+
|
62
60
|
def trigger_observable(observable)
|
63
61
|
observable.execute
|
64
62
|
sleep(0.2)
|
@@ -65,6 +65,7 @@ module Concurrent
|
|
65
65
|
|
66
66
|
after(:each) do
|
67
67
|
subject.stop
|
68
|
+
kill_rogue_threads
|
68
69
|
sleep(0.1)
|
69
70
|
end
|
70
71
|
|
@@ -846,7 +847,7 @@ module Concurrent
|
|
846
847
|
supervisor = Supervisor.new(restart_strategy: :one_for_one,
|
847
848
|
monitor_interval: 0.1)
|
848
849
|
supervisor.add_worker(error_class.new)
|
849
|
-
supervisor.
|
850
|
+
supervisor.stub(:exceeded_max_restart_frequency?).once.and_return(true)
|
850
851
|
future = Concurrent::Future.execute{ supervisor.run }
|
851
852
|
future.value(1)
|
852
853
|
supervisor.should_not be_running
|
data/spec/spec_helper.rb
CHANGED
@@ -28,4 +28,14 @@ Dir[File.join(File.dirname(__FILE__), 'support/**/*.rb')].each { |f| require Fil
|
|
28
28
|
|
29
29
|
RSpec.configure do |config|
|
30
30
|
config.order = 'random'
|
31
|
+
|
32
|
+
config.before(:each) do
|
33
|
+
#TODO: Better configuration management in individual test suites
|
34
|
+
reset_gem_configuration
|
35
|
+
end
|
36
|
+
|
37
|
+
config.after(:each) do
|
38
|
+
#TODO: Better thread management in individual test suites
|
39
|
+
kill_rogue_threads(false)
|
40
|
+
end
|
31
41
|
end
|
@@ -22,27 +22,31 @@ module Concurrent
|
|
22
22
|
RbConfig::CONFIG['ruby_install_name']=~ /^rbx$/i
|
23
23
|
end
|
24
24
|
|
25
|
-
def
|
26
|
-
|
25
|
+
def do_no_reset!
|
26
|
+
@do_not_reset = true
|
27
27
|
end
|
28
28
|
|
29
|
-
|
30
|
-
end
|
31
|
-
end
|
29
|
+
@@killed = false
|
32
30
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
reset_gem_configuration
|
31
|
+
def reset_gem_configuration
|
32
|
+
Concurrent.instance_variable_get(:@configuration).value = Concurrent::Configuration.new if @@killed
|
33
|
+
@@killed = false
|
37
34
|
end
|
38
35
|
|
39
|
-
|
36
|
+
def kill_rogue_threads(warning = true)
|
37
|
+
return if @do_not_reset
|
38
|
+
warn('[DEPRECATED] brute force thread control being used -- tests need updated') if warning
|
40
39
|
Thread.list.each do |thread|
|
41
40
|
thread.kill unless thread == Thread.current
|
42
41
|
end
|
42
|
+
@@killed = true
|
43
43
|
end
|
44
|
+
|
45
|
+
extend self
|
44
46
|
end
|
47
|
+
end
|
45
48
|
|
49
|
+
class RSpec::Core::ExampleGroup
|
46
50
|
include Concurrent::TestHelpers
|
47
51
|
extend Concurrent::TestHelpers
|
48
52
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: concurrent-ruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.6.
|
4
|
+
version: 0.6.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jerry D'Antonio
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-06-14 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: |2
|
14
14
|
Modern concurrency tools including agents, futures, promises, thread pools, actors, supervisors, and more.
|
@@ -18,9 +18,9 @@ executables: []
|
|
18
18
|
extensions: []
|
19
19
|
extra_rdoc_files:
|
20
20
|
- README.md
|
21
|
-
- LICENSE
|
21
|
+
- LICENSE.txt
|
22
22
|
files:
|
23
|
-
- LICENSE
|
23
|
+
- LICENSE.txt
|
24
24
|
- README.md
|
25
25
|
- lib/concurrent.rb
|
26
26
|
- lib/concurrent/actor/actor.rb
|
@@ -31,7 +31,6 @@ files:
|
|
31
31
|
- lib/concurrent/actress/context.rb
|
32
32
|
- lib/concurrent/actress/core.rb
|
33
33
|
- lib/concurrent/actress/core_delegations.rb
|
34
|
-
- lib/concurrent/actress/doc.md
|
35
34
|
- lib/concurrent/actress/envelope.rb
|
36
35
|
- lib/concurrent/actress/errors.rb
|
37
36
|
- lib/concurrent/actress/reference.rb
|
@@ -72,7 +71,6 @@ files:
|
|
72
71
|
- lib/concurrent/executor/java_fixed_thread_pool.rb
|
73
72
|
- lib/concurrent/executor/java_single_thread_executor.rb
|
74
73
|
- lib/concurrent/executor/java_thread_pool_executor.rb
|
75
|
-
- lib/concurrent/executor/one_by_one.rb
|
76
74
|
- lib/concurrent/executor/per_thread_executor.rb
|
77
75
|
- lib/concurrent/executor/ruby_cached_thread_pool.rb
|
78
76
|
- lib/concurrent/executor/ruby_fixed_thread_pool.rb
|
@@ -80,6 +78,7 @@ files:
|
|
80
78
|
- lib/concurrent/executor/ruby_thread_pool_executor.rb
|
81
79
|
- lib/concurrent/executor/ruby_thread_pool_worker.rb
|
82
80
|
- lib/concurrent/executor/safe_task_executor.rb
|
81
|
+
- lib/concurrent/executor/serialized_execution.rb
|
83
82
|
- lib/concurrent/executor/single_thread_executor.rb
|
84
83
|
- lib/concurrent/executor/thread_pool_executor.rb
|
85
84
|
- lib/concurrent/executor/timer_set.rb
|
@@ -1,53 +0,0 @@
|
|
1
|
-
# Light-weighted implement of Actors. Inspired by Akka and Erlang.
|
2
|
-
|
3
|
-
Actors are using a thread-pool by default which makes them very cheap to create and discard.
|
4
|
-
Thousands of actors can be created allowing to brake the program to small maintainable pieces
|
5
|
-
without breaking single responsibility principles.
|
6
|
-
|
7
|
-
## Quick example
|
8
|
-
|
9
|
-
class Counter
|
10
|
-
include Context
|
11
|
-
|
12
|
-
def initialize(initial_value)
|
13
|
-
@count = initial_value
|
14
|
-
end
|
15
|
-
|
16
|
-
def on_message(message)
|
17
|
-
case message
|
18
|
-
when Integer
|
19
|
-
@count += message
|
20
|
-
when :terminate
|
21
|
-
terminate!
|
22
|
-
else
|
23
|
-
raise 'unknown'
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
# create new actor
|
29
|
-
counter = Counter.spawn(:test_counter, 5) # => a Reference
|
30
|
-
|
31
|
-
# send messages
|
32
|
-
counter.tell(1) # => counter
|
33
|
-
counter << 1 # => counter
|
34
|
-
|
35
|
-
# send messages getting an IVar back for synchronization
|
36
|
-
counter.ask(0) # => an ivar
|
37
|
-
counter.ask(0).value # => 7
|
38
|
-
|
39
|
-
# terminate the actor
|
40
|
-
counter.ask(:terminate).wait
|
41
|
-
counter.terminated? # => true
|
42
|
-
counter.ask(5).wait.rejected? # => true
|
43
|
-
|
44
|
-
# failure on message processing will terminate the actor
|
45
|
-
counter = Counter.spawn(:test_counter, 0)
|
46
|
-
counter.ask('boom').wait.rejected? # => true
|
47
|
-
counter.terminated? # => true
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|