concurrent-ruby 0.6.0 → 0.6.1
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/{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
|
-
|