concurrent-ruby 0.1.1.pre.5 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
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