concurrent-ruby 0.1.1.pre.5 → 0.1.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 (45) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -48
  3. data/lib/concurrent.rb +0 -6
  4. data/lib/concurrent/agent.rb +40 -19
  5. data/lib/concurrent/cached_thread_pool.rb +11 -10
  6. data/lib/concurrent/defer.rb +12 -8
  7. data/lib/concurrent/fixed_thread_pool.rb +6 -12
  8. data/lib/concurrent/future.rb +20 -8
  9. data/lib/concurrent/global_thread_pool.rb +0 -13
  10. data/lib/concurrent/goroutine.rb +1 -5
  11. data/lib/concurrent/obligation.rb +64 -10
  12. data/lib/concurrent/promise.rb +60 -38
  13. data/lib/concurrent/thread_pool.rb +5 -16
  14. data/lib/concurrent/utilities.rb +0 -8
  15. data/lib/concurrent/version.rb +1 -1
  16. data/md/defer.md +4 -4
  17. data/md/promise.md +0 -2
  18. data/md/thread_pool.md +0 -27
  19. data/spec/concurrent/agent_spec.rb +27 -8
  20. data/spec/concurrent/cached_thread_pool_spec.rb +1 -14
  21. data/spec/concurrent/defer_spec.rb +21 -17
  22. data/spec/concurrent/event_machine_defer_proxy_spec.rb +149 -159
  23. data/spec/concurrent/fixed_thread_pool_spec.rb +3 -2
  24. data/spec/concurrent/future_spec.rb +10 -3
  25. data/spec/concurrent/goroutine_spec.rb +0 -15
  26. data/spec/concurrent/obligation_shared.rb +2 -16
  27. data/spec/concurrent/promise_spec.rb +13 -15
  28. data/spec/concurrent/thread_pool_shared.rb +5 -5
  29. data/spec/concurrent/utilities_spec.rb +1 -30
  30. data/spec/spec_helper.rb +0 -25
  31. metadata +7 -28
  32. data/lib/concurrent/executor.rb +0 -95
  33. data/lib/concurrent/functions.rb +0 -120
  34. data/lib/concurrent/null_thread_pool.rb +0 -22
  35. data/lib/concurrent/reactor.rb +0 -161
  36. data/lib/concurrent/reactor/drb_async_demux.rb +0 -74
  37. data/lib/concurrent/reactor/tcp_sync_demux.rb +0 -98
  38. data/md/executor.md +0 -176
  39. data/spec/concurrent/executor_spec.rb +0 -200
  40. data/spec/concurrent/functions_spec.rb +0 -217
  41. data/spec/concurrent/global_thread_pool_spec.rb +0 -38
  42. data/spec/concurrent/null_thread_pool_spec.rb +0 -54
  43. data/spec/concurrent/reactor/drb_async_demux_spec.rb +0 -12
  44. data/spec/concurrent/reactor/tcp_sync_demux_spec.rb +0 -12
  45. data/spec/concurrent/reactor_spec.rb +0 -351
@@ -41,7 +41,7 @@ module Concurrent
41
41
  context '#kill' do
42
42
 
43
43
  it 'kills all threads' do
44
- Thread.should_receive(:kill).at_least(5).times
44
+ Thread.should_receive(:kill).exactly(5).times
45
45
  pool = FixedThreadPool.new(5)
46
46
  pool.kill
47
47
  sleep(0.1)
@@ -74,9 +74,10 @@ module Concurrent
74
74
  it 'restarts threads that experience exception' do
75
75
  pool = FixedThreadPool.new(5)
76
76
  3.times{ pool << proc{ raise StandardError } }
77
- sleep(5)
77
+ sleep(2)
78
78
  pool.size.should eq 5
79
79
  pool.status.should_not include(nil)
80
+ #pool.status.include?(nil).should be_false
80
81
  end
81
82
  end
82
83
  end
@@ -9,7 +9,7 @@ module Concurrent
9
9
  let!(:rejected_reason) { StandardError.new('mojo jojo') }
10
10
 
11
11
  let(:pending_subject) do
12
- Future.new{ sleep(3); fulfilled_value }
12
+ Future.new{ sleep(2) }
13
13
  end
14
14
 
15
15
  let(:fulfilled_subject) do
@@ -21,7 +21,7 @@ module Concurrent
21
21
  end
22
22
 
23
23
  before(:each) do
24
- Future.thread_pool = FixedThreadPool.new(1)
24
+ $GLOBAL_THREAD_POOL = CachedThreadPool.new
25
25
  end
26
26
 
27
27
  it_should_behave_like Obligation
@@ -40,7 +40,7 @@ module Concurrent
40
40
  context '#initialize' do
41
41
 
42
42
  it 'spawns a new thread when a block is given' do
43
- Future.thread_pool.should_receive(:post).once.with(any_args())
43
+ $GLOBAL_THREAD_POOL.should_receive(:post).once.with(any_args())
44
44
  Future.new{ nil }
45
45
  end
46
46
 
@@ -102,6 +102,13 @@ module Concurrent
102
102
  it 'aliases #deref for #value' do
103
103
  fulfilled_subject.deref.should eq fulfilled_value
104
104
  end
105
+
106
+ it 'aliases Kernel#future for Future.new' do
107
+ future().should be_a(Future)
108
+ future(){ nil }.should be_a(Future)
109
+ future(1, 2, 3).should be_a(Future)
110
+ future(1, 2, 3){ nil }.should be_a(Future)
111
+ end
105
112
  end
106
113
  end
107
114
  end
@@ -48,20 +48,5 @@ module Concurrent
48
48
  sleep(0.1)
49
49
  @expected.should eq [1,2,3]
50
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
51
  end
67
52
  end
@@ -37,7 +37,7 @@ module Concurrent
37
37
  it 'returns nil when reaching the optional timeout value' do
38
38
  f = pending_subject
39
39
  sleep(0.1)
40
- f.value(0).should be_nil
40
+ f.value(0.1).should be_nil
41
41
  f.should be_pending
42
42
  end
43
43
 
@@ -49,22 +49,8 @@ module Concurrent
49
49
  f.should be_pending
50
50
  end
51
51
 
52
- it 'returns the value when fulfilled before timeout' do
53
- f = pending_subject
54
- sleep(0.1)
55
- f.value(10).should be_true
56
- f.should be_fulfilled
57
- end
58
-
59
- it 'returns nil when timeout reached' do
60
- f = pending_subject
61
- sleep(0.1)
62
- f.value(0.1).should be_nil
63
- f.should be_pending
64
- end
65
-
66
52
  it 'is nil when :pending' do
67
- expected = pending_subject.value(0)
53
+ expected = pending_subject.value
68
54
  expected.should be_nil
69
55
  end
70
56
 
@@ -9,7 +9,7 @@ module Concurrent
9
9
  let!(:rejected_reason) { StandardError.new('mojo jojo') }
10
10
 
11
11
  let(:pending_subject) do
12
- Promise.new{ sleep(3); fulfilled_value }
12
+ Promise.new{ sleep(1) }
13
13
  end
14
14
 
15
15
  let(:fulfilled_subject) do
@@ -22,7 +22,7 @@ module Concurrent
22
22
  end
23
23
 
24
24
  before(:each) do
25
- Promise.thread_pool = FixedThreadPool.new(1)
25
+ $GLOBAL_THREAD_POOL = CachedThreadPool.new
26
26
  end
27
27
 
28
28
  it_should_behave_like Obligation
@@ -163,9 +163,10 @@ module Concurrent
163
163
  end
164
164
 
165
165
  it 'recursively rejects all children' do
166
- p = Promise.new{ raise StandardError.new('Boom!') }
166
+ p = Promise.new{ Thread.pass; raise StandardError.new('Boom!') }
167
167
  promises = 10.times.collect{ p.then{ true } }
168
168
  sleep(0.1)
169
+
169
170
  10.times.each{|i| promises[i].should be_rejected }
170
171
  end
171
172
 
@@ -182,7 +183,7 @@ module Concurrent
182
183
  rescue(StandardError){|ex| @expected = 1 }.
183
184
  rescue(StandardError){|ex| @expected = 2 }.
184
185
  rescue(StandardError){|ex| @expected = 3 }
185
- sleep(0.1)
186
+ sleep(0.1)
186
187
  @expected.should eq 1
187
188
  end
188
189
 
@@ -197,8 +198,6 @@ module Concurrent
197
198
  end
198
199
 
199
200
  it 'searches associated rescue handlers in order' do
200
- Promise.thread_pool = CachedThreadPool.new
201
-
202
201
  @expected = nil
203
202
  Promise.new{ raise ArgumentError }.
204
203
  rescue(ArgumentError){|ex| @expected = 1 }.
@@ -264,7 +263,7 @@ module Concurrent
264
263
 
265
264
  it 'calls matching rescue handlers on all children' do
266
265
  @expected = []
267
- Promise.new{ raise StandardError }.
266
+ Promise.new{ Thread.pass; raise StandardError }.
268
267
  then{ sleep(0.1) }.rescue{ @expected << 'Boom!' }.
269
268
  then{ sleep(0.1) }.rescue{ @expected << 'Boom!' }.
270
269
  then{ sleep(0.1) }.rescue{ @expected << 'Boom!' }.
@@ -274,14 +273,6 @@ module Concurrent
274
273
 
275
274
  @expected.length.should eq 5
276
275
  end
277
-
278
- it 'matches a rescue handler added after rejection' do
279
- @expected = false
280
- p = Promise.new{ raise StandardError }
281
- sleep(0.1)
282
- p.rescue(StandardError){ @expected = true }
283
- @expected.should be_true
284
- end
285
276
  end
286
277
 
287
278
  context 'aliases' do
@@ -307,6 +298,13 @@ module Concurrent
307
298
  sleep(0.1)
308
299
  @expected.should be_true
309
300
  end
301
+
302
+ it 'aliases Kernel#promise for Promise.new' do
303
+ promise().should be_a(Promise)
304
+ promise(){ nil }.should be_a(Promise)
305
+ promise(1, 2, 3).should be_a(Promise)
306
+ promise(1, 2, 3){ nil }.should be_a(Promise)
307
+ end
310
308
  end
311
309
  end
312
310
  end
@@ -29,9 +29,8 @@ module Concurrent
29
29
 
30
30
  context '#shutdown?' do
31
31
 
32
- it 'returns true if #shutdown is complete' do
32
+ it 'returns true if #shutdown has been called' do
33
33
  subject.shutdown
34
- sleep(0.1)
35
34
  subject.should be_shutdown
36
35
  end
37
36
 
@@ -82,9 +81,10 @@ module Concurrent
82
81
  end
83
82
 
84
83
  it 'allows threads to exit normally' do
85
- subject.shutdown
84
+ pool = FixedThreadPool.new(5)
85
+ pool.shutdown
86
86
  sleep(1)
87
- subject.status.should be_empty
87
+ pool.status.should be_empty
88
88
  end
89
89
  end
90
90
 
@@ -139,7 +139,7 @@ module Concurrent
139
139
  it 'returns false when shutdown fails to complete before timeout' do
140
140
  subject.post{ sleep(1) }
141
141
  subject.shutdown
142
- subject.wait_for_termination(0.5).should be_false
142
+ subject.wait_for_termination(0.5).should be_true
143
143
  end
144
144
  end
145
145
 
@@ -1,5 +1,4 @@
1
1
  require 'spec_helper'
2
- require 'thread'
3
2
 
4
3
  describe 'utilities' do
5
4
 
@@ -27,7 +26,7 @@ describe 'utilities' do
27
26
  it 'raises an exception if no block is given' do
28
27
  lambda {
29
28
  atomic()
30
- }.should raise_error(ArgumentError)
29
+ }.should raise_error
31
30
  end
32
31
 
33
32
  it 'creates a new Fiber' do
@@ -43,32 +42,4 @@ describe 'utilities' do
43
42
  atomic{ 'foo' }
44
43
  end
45
44
  end
46
-
47
- context Mutex do
48
-
49
- context '#sync_with_timeout' do
50
-
51
- it 'returns the result of the block if a lock is obtained before timeout' do
52
- mutex = Mutex.new
53
- result = mutex.sync_with_timeout(30){ 42 }
54
- result.should eq 42
55
- end
56
-
57
- it 'raises Timeout::Error if the timeout is exceeded' do
58
- mutex = Mutex.new
59
- thread = Thread.new{ mutex.synchronize{ sleep(30) } }
60
- sleep(0.1)
61
- lambda {
62
- mutex.sync_and_wait(1)
63
- }.should raise_error(NoMethodError)
64
- Thread.kill(thread)
65
- end
66
-
67
- it 'raises an exception if no block given' do
68
- lambda {
69
- Mutex.new.sync_with_timeout()
70
- }.should raise_error(ArgumentError)
71
- end
72
- end
73
- end
74
45
  end
@@ -1,36 +1,11 @@
1
- require 'simplecov'
2
- SimpleCov.start do
3
- project_name 'concurrent-ruby'
4
- add_filter '/md/'
5
- add_filter '/pkg/'
6
- add_filter '/spec/'
7
- add_filter '/tasks/'
8
- end
9
-
10
1
  require 'eventmachine'
11
2
 
12
3
  require 'concurrent'
13
- require 'concurrent/functions'
14
-
15
- require 'rbconfig'
16
-
17
- def mri?
18
- RbConfig::CONFIG['ruby_install_name'] =~ /^ruby$/i
19
- end
20
-
21
- def jruby?
22
- RbConfig::CONFIG['ruby_install_name'] =~ /^jruby$/i
23
- end
24
-
25
- def rbx?
26
- RbConfig::CONFIG['ruby_install_name'] =~ /^rbx$/i
27
- end
28
4
 
29
5
  # import all the support files
30
6
  Dir[File.join(File.dirname(__FILE__), 'support/**/*.rb')].each { |f| require File.expand_path(f) }
31
7
 
32
8
  RSpec.configure do |config|
33
- config.order = 'random'
34
9
 
35
10
  config.before(:suite) do
36
11
  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.1.1.pre.5
4
+ version: 0.1.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: 2013-08-15 00:00:00.000000000 Z
11
+ date: 2013-07-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: functional-ruby
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - ~>
18
18
  - !ruby/object:Gem::Version
19
- version: 0.7.1
19
+ version: 0.7.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ~>
25
25
  - !ruby/object:Gem::Version
26
- version: 0.7.1
26
+ version: 0.7.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: bundler
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -54,18 +54,12 @@ files:
54
54
  - lib/concurrent/defer.rb
55
55
  - lib/concurrent/event.rb
56
56
  - lib/concurrent/event_machine_defer_proxy.rb
57
- - lib/concurrent/executor.rb
58
57
  - lib/concurrent/fixed_thread_pool.rb
59
- - lib/concurrent/functions.rb
60
58
  - lib/concurrent/future.rb
61
59
  - lib/concurrent/global_thread_pool.rb
62
60
  - lib/concurrent/goroutine.rb
63
- - lib/concurrent/null_thread_pool.rb
64
61
  - lib/concurrent/obligation.rb
65
62
  - lib/concurrent/promise.rb
66
- - lib/concurrent/reactor/drb_async_demux.rb
67
- - lib/concurrent/reactor/tcp_sync_demux.rb
68
- - lib/concurrent/reactor.rb
69
63
  - lib/concurrent/thread_pool.rb
70
64
  - lib/concurrent/utilities.rb
71
65
  - lib/concurrent/version.rb
@@ -74,7 +68,6 @@ files:
74
68
  - md/agent.md
75
69
  - md/defer.md
76
70
  - md/event.md
77
- - md/executor.md
78
71
  - md/future.md
79
72
  - md/goroutine.md
80
73
  - md/obligation.md
@@ -85,18 +78,11 @@ files:
85
78
  - spec/concurrent/defer_spec.rb
86
79
  - spec/concurrent/event_machine_defer_proxy_spec.rb
87
80
  - spec/concurrent/event_spec.rb
88
- - spec/concurrent/executor_spec.rb
89
81
  - spec/concurrent/fixed_thread_pool_spec.rb
90
- - spec/concurrent/functions_spec.rb
91
82
  - spec/concurrent/future_spec.rb
92
- - spec/concurrent/global_thread_pool_spec.rb
93
83
  - spec/concurrent/goroutine_spec.rb
94
- - spec/concurrent/null_thread_pool_spec.rb
95
84
  - spec/concurrent/obligation_shared.rb
96
85
  - spec/concurrent/promise_spec.rb
97
- - spec/concurrent/reactor/drb_async_demux_spec.rb
98
- - spec/concurrent/reactor/tcp_sync_demux_spec.rb
99
- - spec/concurrent/reactor_spec.rb
100
86
  - spec/concurrent/thread_pool_shared.rb
101
87
  - spec/concurrent/utilities_spec.rb
102
88
  - spec/spec_helper.rb
@@ -115,12 +101,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
115
101
  version: 1.9.2
116
102
  required_rubygems_version: !ruby/object:Gem::Requirement
117
103
  requirements:
118
- - - '>'
104
+ - - '>='
119
105
  - !ruby/object:Gem::Version
120
- version: 1.3.1
106
+ version: '0'
121
107
  requirements: []
122
108
  rubyforge_project:
123
- rubygems_version: 2.0.6
109
+ rubygems_version: 2.0.3
124
110
  signing_key:
125
111
  specification_version: 4
126
112
  summary: Erlang, Clojure, and Go inspired concurrent programming tools for Ruby.
@@ -130,18 +116,11 @@ test_files:
130
116
  - spec/concurrent/defer_spec.rb
131
117
  - spec/concurrent/event_machine_defer_proxy_spec.rb
132
118
  - spec/concurrent/event_spec.rb
133
- - spec/concurrent/executor_spec.rb
134
119
  - spec/concurrent/fixed_thread_pool_spec.rb
135
- - spec/concurrent/functions_spec.rb
136
120
  - spec/concurrent/future_spec.rb
137
- - spec/concurrent/global_thread_pool_spec.rb
138
121
  - spec/concurrent/goroutine_spec.rb
139
- - spec/concurrent/null_thread_pool_spec.rb
140
122
  - spec/concurrent/obligation_shared.rb
141
123
  - spec/concurrent/promise_spec.rb
142
- - spec/concurrent/reactor/drb_async_demux_spec.rb
143
- - spec/concurrent/reactor/tcp_sync_demux_spec.rb
144
- - spec/concurrent/reactor_spec.rb
145
124
  - spec/concurrent/thread_pool_shared.rb
146
125
  - spec/concurrent/utilities_spec.rb
147
126
  - spec/spec_helper.rb
@@ -1,95 +0,0 @@
1
- require 'thread'
2
-
3
- module Concurrent
4
-
5
- module Executor
6
- extend self
7
-
8
- class ExecutionContext
9
- attr_reader :name
10
- attr_reader :execution_interval
11
- attr_reader :timeout_interval
12
-
13
- protected
14
-
15
- def initialize(name, execution_interval, timeout_interval, thread)
16
- @name = name
17
- @execution_interval = execution_interval
18
- @timeout_interval = timeout_interval
19
- @thread = thread
20
- @thread[:stop] = false
21
- end
22
-
23
- public
24
-
25
- def status
26
- return @thread.status unless @thread.nil?
27
- end
28
-
29
- def join(limit = nil)
30
- if @thread.nil?
31
- return nil
32
- elsif limit.nil?
33
- return @thread.join
34
- else
35
- return @thread.join(limit)
36
- end
37
- end
38
-
39
- def stop
40
- @thread[:stop] = true
41
- end
42
-
43
- def kill
44
- unless @thread.nil?
45
- stop
46
- Thread.kill(@thread)
47
- @thread = nil
48
- end
49
- end
50
- alias_method :terminate, :kill
51
- end
52
-
53
- EXECUTION_INTERVAL = 60
54
- TIMEOUT_INTERVAL = 30
55
-
56
- STDOUT_LOGGER = proc do |name, level, msg|
57
- print "%5s (%s) %s: %s\n" % [level.upcase, Time.now.strftime("%F %T"), name, msg]
58
- end
59
-
60
- def run(name, opts = {})
61
- raise ArgumentError.new('no block given') unless block_given?
62
-
63
- execution_interval = opts[:execution] || opts[:execution_interval] || EXECUTION_INTERVAL
64
- timeout_interval = opts[:timeout] || opts[:timeout_interval] || TIMEOUT_INTERVAL
65
- run_now = opts[:now] || opts[:run_now] || false
66
- logger = opts[:logger] || STDOUT_LOGGER
67
- block_args = opts[:args] || opts [:arguments] || []
68
-
69
- executor = Thread.new(*block_args) do |*args|
70
- sleep(execution_interval) unless run_now == true
71
- loop do
72
- break if Thread.current[:stop]
73
- begin
74
- worker = Thread.new{ yield(*args) }
75
- worker.abort_on_exception = false
76
- if worker.join(timeout_interval).nil?
77
- logger.call(name, :warn, "execution timed out after #{timeout_interval} seconds")
78
- else
79
- logger.call(name, :info, 'execution completed successfully')
80
- end
81
- rescue Exception => ex
82
- logger.call(name, :error, "execution failed with error '#{ex}'")
83
- ensure
84
- Thread.kill(worker)
85
- worker = nil
86
- end
87
- break if Thread.current[:stop]
88
- sleep(execution_interval)
89
- end
90
- end
91
-
92
- return ExecutionContext.new(name, execution_interval, timeout_interval, executor)
93
- end
94
- end
95
- end