concurrent-ruby 0.2.0 → 0.2.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.
Files changed (57) hide show
  1. data/LICENSE +21 -21
  2. data/README.md +275 -275
  3. data/lib/concurrent.rb +28 -28
  4. data/lib/concurrent/agent.rb +114 -114
  5. data/lib/concurrent/cached_thread_pool.rb +131 -129
  6. data/lib/concurrent/defer.rb +65 -65
  7. data/lib/concurrent/event.rb +60 -60
  8. data/lib/concurrent/event_machine_defer_proxy.rb +23 -23
  9. data/lib/concurrent/executor.rb +96 -95
  10. data/lib/concurrent/fixed_thread_pool.rb +99 -95
  11. data/lib/concurrent/functions.rb +120 -120
  12. data/lib/concurrent/future.rb +42 -42
  13. data/lib/concurrent/global_thread_pool.rb +16 -16
  14. data/lib/concurrent/goroutine.rb +29 -29
  15. data/lib/concurrent/null_thread_pool.rb +22 -22
  16. data/lib/concurrent/obligation.rb +67 -67
  17. data/lib/concurrent/promise.rb +174 -174
  18. data/lib/concurrent/reactor.rb +166 -166
  19. data/lib/concurrent/reactor/drb_async_demux.rb +83 -83
  20. data/lib/concurrent/reactor/tcp_sync_demux.rb +131 -131
  21. data/lib/concurrent/supervisor.rb +105 -100
  22. data/lib/concurrent/thread_pool.rb +76 -76
  23. data/lib/concurrent/utilities.rb +32 -32
  24. data/lib/concurrent/version.rb +3 -3
  25. data/lib/concurrent_ruby.rb +1 -1
  26. data/md/agent.md +123 -123
  27. data/md/defer.md +174 -174
  28. data/md/event.md +32 -32
  29. data/md/executor.md +187 -187
  30. data/md/future.md +83 -83
  31. data/md/goroutine.md +52 -52
  32. data/md/obligation.md +32 -32
  33. data/md/promise.md +227 -227
  34. data/md/thread_pool.md +224 -224
  35. data/spec/concurrent/agent_spec.rb +386 -386
  36. data/spec/concurrent/cached_thread_pool_spec.rb +125 -125
  37. data/spec/concurrent/defer_spec.rb +195 -195
  38. data/spec/concurrent/event_machine_defer_proxy_spec.rb +256 -256
  39. data/spec/concurrent/event_spec.rb +134 -134
  40. data/spec/concurrent/executor_spec.rb +200 -200
  41. data/spec/concurrent/fixed_thread_pool_spec.rb +83 -83
  42. data/spec/concurrent/functions_spec.rb +217 -217
  43. data/spec/concurrent/future_spec.rb +108 -108
  44. data/spec/concurrent/global_thread_pool_spec.rb +38 -38
  45. data/spec/concurrent/goroutine_spec.rb +67 -67
  46. data/spec/concurrent/null_thread_pool_spec.rb +57 -54
  47. data/spec/concurrent/obligation_shared.rb +132 -132
  48. data/spec/concurrent/promise_spec.rb +312 -312
  49. data/spec/concurrent/reactor/drb_async_demux_spec.rb +196 -196
  50. data/spec/concurrent/reactor/tcp_sync_demux_spec.rb +410 -410
  51. data/spec/concurrent/reactor_spec.rb +364 -364
  52. data/spec/concurrent/supervisor_spec.rb +269 -258
  53. data/spec/concurrent/thread_pool_shared.rb +204 -204
  54. data/spec/concurrent/utilities_spec.rb +74 -74
  55. data/spec/spec_helper.rb +32 -32
  56. metadata +20 -16
  57. checksums.yaml +0 -7
@@ -1,108 +1,108 @@
1
- require 'spec_helper'
2
- require_relative 'obligation_shared'
3
-
4
- module Concurrent
5
-
6
- describe Future do
7
-
8
- let!(:fulfilled_value) { 10 }
9
- let!(:rejected_reason) { StandardError.new('mojo jojo') }
10
-
11
- let(:pending_subject) do
12
- Future.new{ sleep(3); fulfilled_value }
13
- end
14
-
15
- let(:fulfilled_subject) do
16
- Future.new{ fulfilled_value }.tap(){ sleep(0.1) }
17
- end
18
-
19
- let(:rejected_subject) do
20
- Future.new{ raise rejected_reason }.tap(){ sleep(0.1) }
21
- end
22
-
23
- before(:each) do
24
- Future.thread_pool = FixedThreadPool.new(1)
25
- end
26
-
27
- it_should_behave_like Concurrent::Obligation
28
-
29
- context 'behavior' do
30
-
31
- it 'implements :future behavior' do
32
- lambda {
33
- Future.new{ nil }
34
- }.should_not raise_error
35
-
36
- Future.new{ nil }.behaves_as?(:future).should be_true
37
- end
38
- end
39
-
40
- context '#initialize' do
41
-
42
- it 'spawns a new thread when a block is given' do
43
- Future.thread_pool.should_receive(:post).once.with(any_args())
44
- Future.new{ nil }
45
- end
46
-
47
- it 'does not spawns a new thread when no block given' do
48
- Thread.should_not_receive(:new).with(any_args())
49
- Future.new
50
- end
51
-
52
- it 'immediately sets the state to :fulfilled when no block given' do
53
- Future.new.should be_fulfilled
54
- end
55
-
56
- it 'immediately sets the value to nil when no block given' do
57
- Future.new.value.should be_nil
58
- end
59
- end
60
-
61
- context 'fulfillment' do
62
-
63
- it 'passes all arguments to handler' do
64
- @a = @b = @c = nil
65
- f = Future.new(1, 2, 3) do |a, b, c|
66
- @a, @b, @c = a, b, c
67
- end
68
- sleep(0.1)
69
- [@a, @b, @c].should eq [1, 2, 3]
70
- end
71
-
72
- it 'sets the value to the result of the handler' do
73
- f = Future.new(10){|a| a * 2 }
74
- sleep(0.1)
75
- f.value.should eq 20
76
- end
77
-
78
- it 'sets the state to :fulfilled when the block completes' do
79
- f = Future.new(10){|a| a * 2 }
80
- sleep(0.1)
81
- f.should be_fulfilled
82
- end
83
-
84
- it 'sets the value to nil when the handler raises an exception' do
85
- f = Future.new{ raise StandardError }
86
- sleep(0.1)
87
- f.value.should be_nil
88
- end
89
-
90
- it 'sets the state to :rejected when the handler raises an exception' do
91
- f = Future.new{ raise StandardError }
92
- sleep(0.1)
93
- f.should be_rejected
94
- end
95
-
96
- context 'aliases' do
97
-
98
- it 'aliases #realized? for #fulfilled?' do
99
- fulfilled_subject.should be_realized
100
- end
101
-
102
- it 'aliases #deref for #value' do
103
- fulfilled_subject.deref.should eq fulfilled_value
104
- end
105
- end
106
- end
107
- end
108
- end
1
+ require 'spec_helper'
2
+ require_relative 'obligation_shared'
3
+
4
+ module Concurrent
5
+
6
+ describe Future do
7
+
8
+ let!(:fulfilled_value) { 10 }
9
+ let!(:rejected_reason) { StandardError.new('mojo jojo') }
10
+
11
+ let(:pending_subject) do
12
+ Future.new{ sleep(3); fulfilled_value }
13
+ end
14
+
15
+ let(:fulfilled_subject) do
16
+ Future.new{ fulfilled_value }.tap(){ sleep(0.1) }
17
+ end
18
+
19
+ let(:rejected_subject) do
20
+ Future.new{ raise rejected_reason }.tap(){ sleep(0.1) }
21
+ end
22
+
23
+ before(:each) do
24
+ Future.thread_pool = FixedThreadPool.new(1)
25
+ end
26
+
27
+ it_should_behave_like Concurrent::Obligation
28
+
29
+ context 'behavior' do
30
+
31
+ it 'implements :future behavior' do
32
+ lambda {
33
+ Future.new{ nil }
34
+ }.should_not raise_error
35
+
36
+ Future.new{ nil }.behaves_as?(:future).should be_true
37
+ end
38
+ end
39
+
40
+ context '#initialize' do
41
+
42
+ it 'spawns a new thread when a block is given' do
43
+ Future.thread_pool.should_receive(:post).once.with(any_args())
44
+ Future.new{ nil }
45
+ end
46
+
47
+ it 'does not spawns a new thread when no block given' do
48
+ Thread.should_not_receive(:new).with(any_args())
49
+ Future.new
50
+ end
51
+
52
+ it 'immediately sets the state to :fulfilled when no block given' do
53
+ Future.new.should be_fulfilled
54
+ end
55
+
56
+ it 'immediately sets the value to nil when no block given' do
57
+ Future.new.value.should be_nil
58
+ end
59
+ end
60
+
61
+ context 'fulfillment' do
62
+
63
+ it 'passes all arguments to handler' do
64
+ @a = @b = @c = nil
65
+ f = Future.new(1, 2, 3) do |a, b, c|
66
+ @a, @b, @c = a, b, c
67
+ end
68
+ sleep(0.1)
69
+ [@a, @b, @c].should eq [1, 2, 3]
70
+ end
71
+
72
+ it 'sets the value to the result of the handler' do
73
+ f = Future.new(10){|a| a * 2 }
74
+ sleep(0.1)
75
+ f.value.should eq 20
76
+ end
77
+
78
+ it 'sets the state to :fulfilled when the block completes' do
79
+ f = Future.new(10){|a| a * 2 }
80
+ sleep(0.1)
81
+ f.should be_fulfilled
82
+ end
83
+
84
+ it 'sets the value to nil when the handler raises an exception' do
85
+ f = Future.new{ raise StandardError }
86
+ sleep(0.1)
87
+ f.value.should be_nil
88
+ end
89
+
90
+ it 'sets the state to :rejected when the handler raises an exception' do
91
+ f = Future.new{ raise StandardError }
92
+ sleep(0.1)
93
+ f.should be_rejected
94
+ end
95
+
96
+ context 'aliases' do
97
+
98
+ it 'aliases #realized? for #fulfilled?' do
99
+ fulfilled_subject.should be_realized
100
+ end
101
+
102
+ it 'aliases #deref for #value' do
103
+ fulfilled_subject.deref.should eq fulfilled_value
104
+ end
105
+ end
106
+ end
107
+ end
108
+ end
@@ -1,38 +1,38 @@
1
- require 'spec_helper'
2
-
3
- module Concurrent
4
-
5
- describe UsesGlobalThreadPool do
6
-
7
- before(:each) do
8
- $GLOBAL_THREAD_POOL = FixedThreadPool.new(1)
9
- end
10
-
11
- it 'defaults to the global thread pool' do
12
- clazz = Class.new{ include UsesGlobalThreadPool }
13
- clazz.thread_pool.should eq $GLOBAL_THREAD_POOL
14
- end
15
-
16
- it 'sets and gets the thread pool for the class' do
17
- pool = NullThreadPool.new
18
- clazz = Class.new{ include UsesGlobalThreadPool }
19
-
20
- clazz.thread_pool = pool
21
- clazz.thread_pool.should eq pool
22
- end
23
-
24
- it 'gives each class its own thread pool' do
25
- clazz1 = Class.new{ include UsesGlobalThreadPool }
26
- clazz2 = Class.new{ include UsesGlobalThreadPool }
27
- clazz3 = Class.new{ include UsesGlobalThreadPool }
28
-
29
- clazz1.thread_pool = FixedThreadPool.new(1)
30
- clazz2.thread_pool = CachedThreadPool.new
31
- clazz3.thread_pool = NullThreadPool.new
32
-
33
- clazz1.thread_pool.should_not eq clazz2.thread_pool
34
- clazz2.thread_pool.should_not eq clazz3.thread_pool
35
- clazz3.thread_pool.should_not eq clazz1.thread_pool
36
- end
37
- end
38
- end
1
+ require 'spec_helper'
2
+
3
+ module Concurrent
4
+
5
+ describe UsesGlobalThreadPool do
6
+
7
+ before(:each) do
8
+ $GLOBAL_THREAD_POOL = FixedThreadPool.new(1)
9
+ end
10
+
11
+ it 'defaults to the global thread pool' do
12
+ clazz = Class.new{ include UsesGlobalThreadPool }
13
+ clazz.thread_pool.should eq $GLOBAL_THREAD_POOL
14
+ end
15
+
16
+ it 'sets and gets the thread pool for the class' do
17
+ pool = NullThreadPool.new
18
+ clazz = Class.new{ include UsesGlobalThreadPool }
19
+
20
+ clazz.thread_pool = pool
21
+ clazz.thread_pool.should eq pool
22
+ end
23
+
24
+ it 'gives each class its own thread pool' do
25
+ clazz1 = Class.new{ include UsesGlobalThreadPool }
26
+ clazz2 = Class.new{ include UsesGlobalThreadPool }
27
+ clazz3 = Class.new{ include UsesGlobalThreadPool }
28
+
29
+ clazz1.thread_pool = FixedThreadPool.new(1)
30
+ clazz2.thread_pool = CachedThreadPool.new
31
+ clazz3.thread_pool = NullThreadPool.new
32
+
33
+ clazz1.thread_pool.should_not eq clazz2.thread_pool
34
+ clazz2.thread_pool.should_not eq clazz3.thread_pool
35
+ clazz3.thread_pool.should_not eq clazz1.thread_pool
36
+ end
37
+ end
38
+ end
@@ -1,67 +1,67 @@
1
- require 'spec_helper'
2
-
3
- module Concurrent
4
-
5
- describe '#go' do
6
-
7
- before(:each) do
8
- $GLOBAL_THREAD_POOL = CachedThreadPool.new
9
- end
10
-
11
- it 'passes all arguments to the block' do
12
- @expected = nil
13
- go(1, 2, 3){|a, b, c| @expected = [c, b, a] }
14
- sleep(0.1)
15
- @expected.should eq [3, 2, 1]
16
- end
17
-
18
- it 'returns true if the thread is successfully created' do
19
- $GLOBAL_THREAD_POOL.should_receive(:post).and_return(true)
20
- go{ nil }.should be_true
21
- end
22
-
23
- it 'returns false if the thread cannot be created' do
24
- $GLOBAL_THREAD_POOL.should_receive(:post).and_return(false)
25
- go{ nil }.should be_false
26
- end
27
-
28
- it 'immediately returns false if no block is given' do
29
- go().should be_false
30
- end
31
-
32
- it 'does not create a thread if no block is given' do
33
- $GLOBAL_THREAD_POOL.should_not_receive(:post)
34
- go()
35
- sleep(0.1)
36
- end
37
-
38
- it 'supresses exceptions on the thread' do
39
- lambda{
40
- go{ raise StandardError }
41
- sleep(0.1)
42
- }.should_not raise_error
43
- end
44
-
45
- it 'processes the block' do
46
- @expected = false
47
- go(1,2,3){|*args| @expected = args }
48
- sleep(0.1)
49
- @expected.should eq [1,2,3]
50
- end
51
-
52
- it 'accepts an alternate thread pool as the first argument' do
53
- pool = Concurrent::FixedThreadPool.new(2)
54
- pool.should_receive(:post).with(no_args())
55
- go(pool){ sleep(0.1) }
56
- sleep(0.2)
57
- end
58
-
59
- it 'passes all other arguments to the block when a thread pool is given' do
60
- @expected = nil
61
- pool = Concurrent::FixedThreadPool.new(2)
62
- go(pool, 1, 2, 3){|a, b, c| @expected = [c, b, a] }
63
- sleep(0.1)
64
- @expected.should eq [3, 2, 1]
65
- end
66
- end
67
- end
1
+ require 'spec_helper'
2
+
3
+ module Concurrent
4
+
5
+ describe '#go' do
6
+
7
+ before(:each) do
8
+ $GLOBAL_THREAD_POOL = CachedThreadPool.new
9
+ end
10
+
11
+ it 'passes all arguments to the block' do
12
+ @expected = nil
13
+ go(1, 2, 3){|a, b, c| @expected = [c, b, a] }
14
+ sleep(0.1)
15
+ @expected.should eq [3, 2, 1]
16
+ end
17
+
18
+ it 'returns true if the thread is successfully created' do
19
+ $GLOBAL_THREAD_POOL.should_receive(:post).and_return(true)
20
+ go{ nil }.should be_true
21
+ end
22
+
23
+ it 'returns false if the thread cannot be created' do
24
+ $GLOBAL_THREAD_POOL.should_receive(:post).and_return(false)
25
+ go{ nil }.should be_false
26
+ end
27
+
28
+ it 'immediately returns false if no block is given' do
29
+ go().should be_false
30
+ end
31
+
32
+ it 'does not create a thread if no block is given' do
33
+ $GLOBAL_THREAD_POOL.should_not_receive(:post)
34
+ go()
35
+ sleep(0.1)
36
+ end
37
+
38
+ it 'supresses exceptions on the thread' do
39
+ lambda{
40
+ go{ raise StandardError }
41
+ sleep(0.1)
42
+ }.should_not raise_error
43
+ end
44
+
45
+ it 'processes the block' do
46
+ @expected = false
47
+ go(1,2,3){|*args| @expected = args }
48
+ sleep(0.1)
49
+ @expected.should eq [1,2,3]
50
+ end
51
+
52
+ it 'accepts an alternate thread pool as the first argument' do
53
+ pool = Concurrent::FixedThreadPool.new(2)
54
+ pool.should_receive(:post).with(no_args())
55
+ go(pool){ sleep(0.1) }
56
+ sleep(0.2)
57
+ end
58
+
59
+ it 'passes all other arguments to the block when a thread pool is given' do
60
+ @expected = nil
61
+ pool = Concurrent::FixedThreadPool.new(2)
62
+ go(pool, 1, 2, 3){|a, b, c| @expected = [c, b, a] }
63
+ sleep(0.1)
64
+ @expected.should eq [3, 2, 1]
65
+ end
66
+ end
67
+ end
@@ -1,54 +1,57 @@
1
- require 'spec_helper'
2
-
3
- require 'concurrent/goroutine'
4
-
5
- module Concurrent
6
-
7
- describe NullThreadPool do
8
-
9
- subject { NullThreadPool.new }
10
-
11
- after(:all) do
12
- $GLOBAL_THREAD_POOL = FixedThreadPool.new(1)
13
- end
14
-
15
- context '#post' do
16
-
17
- it 'proxies a call without arguments' do
18
- Thread.should_receive(:new).with(no_args())
19
- $GLOBAL_THREAD_POOL.should_not_receive(:post).with(any_args())
20
- subject.post{ nil }
21
- end
22
-
23
- it 'proxies a call with arguments' do
24
- Thread.should_receive(:new).with(1,2,3)
25
- $GLOBAL_THREAD_POOL.should_not_receive(:post).with(any_args())
26
- subject.post(1,2,3){ nil }
27
- end
28
-
29
- it 'aliases #<<' do
30
- Thread.should_receive(:new).with(no_args())
31
- $GLOBAL_THREAD_POOL.should_not_receive(:post).with(any_args())
32
- subject << proc{ nil }
33
- end
34
- end
35
-
36
- context 'operation' do
37
-
38
- context 'goroutine' do
39
-
40
- it 'gets a new thread' do
41
- $GLOBAL_THREAD_POOL = subject
42
-
43
- t = Thread.new{ nil }
44
-
45
- Thread.should_receive(:new).with(no_args()).and_return(t)
46
- go{ nil }
47
-
48
- Thread.should_receive(:new).with(1,2,3).and_return(t)
49
- go(1,2,3){ nil }
50
- end
51
- end
52
- end
53
- end
54
- end
1
+ require 'spec_helper'
2
+
3
+ require 'concurrent/goroutine'
4
+
5
+ module Concurrent
6
+
7
+ describe NullThreadPool do
8
+
9
+ subject { NullThreadPool.new }
10
+
11
+ after(:all) do
12
+ $GLOBAL_THREAD_POOL = FixedThreadPool.new(1)
13
+ end
14
+
15
+ context '#post' do
16
+
17
+ it 'proxies a call without arguments' do
18
+ thread = Thread.new{ nil }
19
+ Thread.should_receive(:new).with(no_args()).and_return(thread)
20
+ $GLOBAL_THREAD_POOL.should_not_receive(:post).with(any_args())
21
+ subject.post{ nil }
22
+ end
23
+
24
+ it 'proxies a call with arguments' do
25
+ thread = Thread.new{ nil }
26
+ Thread.should_receive(:new).with(1,2,3).and_return(thread)
27
+ $GLOBAL_THREAD_POOL.should_not_receive(:post).with(any_args())
28
+ subject.post(1,2,3){ nil }
29
+ end
30
+
31
+ it 'aliases #<<' do
32
+ thread = Thread.new{ nil }
33
+ Thread.should_receive(:new).with(no_args()).and_return(thread)
34
+ $GLOBAL_THREAD_POOL.should_not_receive(:post).with(any_args())
35
+ subject << proc{ nil }
36
+ end
37
+ end
38
+
39
+ context 'operation' do
40
+
41
+ context 'goroutine' do
42
+
43
+ it 'gets a new thread' do
44
+ $GLOBAL_THREAD_POOL = subject
45
+
46
+ t = Thread.new{ nil }
47
+
48
+ Thread.should_receive(:new).with(no_args()).and_return(t)
49
+ go{ nil }
50
+
51
+ Thread.should_receive(:new).with(1,2,3).and_return(t)
52
+ go(1,2,3){ nil }
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end