concurrent-ruby 0.1.1.pre.2 → 0.1.1.pre.3

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.
@@ -21,7 +21,7 @@ module Concurrent
21
21
  end
22
22
 
23
23
  before(:each) do
24
- $GLOBAL_THREAD_POOL = FixedThreadPool.new(2)
24
+ Future.thread_pool = FixedThreadPool.new(1)
25
25
  end
26
26
 
27
27
  it_should_behave_like Obligation
@@ -40,17 +40,10 @@ module Concurrent
40
40
  context '#initialize' do
41
41
 
42
42
  it 'spawns a new thread when a block is given' do
43
- $GLOBAL_THREAD_POOL.should_receive(:post).once.with(any_args())
43
+ Future.thread_pool.should_receive(:post).once.with(any_args())
44
44
  Future.new{ nil }
45
45
  end
46
46
 
47
- it 'accepts an alternate thread pool as the first argument' do
48
- pool = Concurrent::FixedThreadPool.new(2)
49
- pool.should_receive(:post).with(no_args())
50
- Future.new(pool, 1, 2, 3){ nil }
51
- sleep(0.1)
52
- end
53
-
54
47
  it 'does not spawns a new thread when no block given' do
55
48
  Thread.should_not_receive(:new).with(any_args())
56
49
  Future.new
@@ -76,16 +69,6 @@ module Concurrent
76
69
  [@a, @b, @c].should eq [1, 2, 3]
77
70
  end
78
71
 
79
- it 'passes all other arguments to the handler when a thread pool is given' do
80
- @expected = nil
81
- pool = Concurrent::FixedThreadPool.new(2)
82
- f = Future.new(pool, 1, 2, 3) do |a, b, c|
83
- @a, @b, @c = a, b, c
84
- end
85
- sleep(0.1)
86
- [@a, @b, @c].should eq [1, 2, 3]
87
- end
88
-
89
72
  it 'sets the value to the result of the handler' do
90
73
  f = Future.new(10){|a| a * 2 }
91
74
  sleep(0.1)
@@ -0,0 +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
@@ -0,0 +1,54 @@
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
@@ -21,6 +21,10 @@ module Concurrent
21
21
  rescue{ nil }.tap(){ sleep(0.1) }
22
22
  end
23
23
 
24
+ before(:each) do
25
+ Promise.thread_pool = FixedThreadPool.new(1)
26
+ end
27
+
24
28
  it_should_behave_like Obligation
25
29
 
26
30
  context 'behavior' do
@@ -194,6 +198,8 @@ module Concurrent
194
198
  end
195
199
 
196
200
  it 'searches associated rescue handlers in order' do
201
+ Promise.thread_pool = CachedThreadPool.new
202
+
197
203
  @expected = nil
198
204
  Promise.new{ raise ArgumentError }.
199
205
  rescue(ArgumentError){|ex| @expected = 1 }.
@@ -0,0 +1,12 @@
1
+ require 'spec_helper'
2
+
3
+ module Concurrent
4
+ class Reactor
5
+
6
+ describe DRbAsyncDemux do
7
+
8
+ pending
9
+
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ require 'spec_helper'
2
+
3
+ module Concurrent
4
+ class Reactor
5
+
6
+ describe TcpSyncDemux do
7
+
8
+ pending
9
+
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,10 @@
1
+ require 'spec_helper'
2
+
3
+ module Concurrent
4
+
5
+ describe Reactor do
6
+
7
+ pending
8
+
9
+ end
10
+ end
@@ -29,8 +29,9 @@ module Concurrent
29
29
 
30
30
  context '#shutdown?' do
31
31
 
32
- it 'returns true if #shutdown has been called' do
32
+ it 'returns true if #shutdown is complete' do
33
33
  subject.shutdown
34
+ sleep(0.1)
34
35
  subject.should be_shutdown
35
36
  end
36
37
 
@@ -139,7 +140,7 @@ module Concurrent
139
140
  it 'returns false when shutdown fails to complete before timeout' do
140
141
  subject.post{ sleep(1) }
141
142
  subject.shutdown
142
- subject.wait_for_termination(0.5).should be_true
143
+ subject.wait_for_termination(0.5).should be_false
143
144
  end
144
145
  end
145
146
 
@@ -1,3 +1,12 @@
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
+
1
10
  require 'eventmachine'
2
11
 
3
12
  require 'concurrent'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: concurrent-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1.pre.2
4
+ version: 0.1.1.pre.3
5
5
  prerelease: 6
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-08-08 00:00:00.000000000 Z
12
+ date: 2013-08-12 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: functional-ruby
@@ -59,7 +59,6 @@ files:
59
59
  - lib/concurrent/agent.rb
60
60
  - lib/concurrent/cached_thread_pool.rb
61
61
  - lib/concurrent/defer.rb
62
- - lib/concurrent/drb_async_demux.rb
63
62
  - lib/concurrent/event.rb
64
63
  - lib/concurrent/event_machine_defer_proxy.rb
65
64
  - lib/concurrent/executor.rb
@@ -68,11 +67,13 @@ files:
68
67
  - lib/concurrent/future.rb
69
68
  - lib/concurrent/global_thread_pool.rb
70
69
  - lib/concurrent/goroutine.rb
70
+ - lib/concurrent/null_thread_pool.rb
71
71
  - lib/concurrent/obligation.rb
72
72
  - lib/concurrent/promise.rb
73
+ - lib/concurrent/reactor/drb_async_demux.rb
74
+ - lib/concurrent/reactor/tcp_sync_demux.rb
73
75
  - lib/concurrent/reactor.rb
74
76
  - lib/concurrent/smart_mutex.rb
75
- - lib/concurrent/tcp_sync_demux.rb
76
77
  - lib/concurrent/thread_pool.rb
77
78
  - lib/concurrent/utilities.rb
78
79
  - lib/concurrent/version.rb
@@ -96,9 +97,14 @@ files:
96
97
  - spec/concurrent/fixed_thread_pool_spec.rb
97
98
  - spec/concurrent/functions_spec.rb
98
99
  - spec/concurrent/future_spec.rb
100
+ - spec/concurrent/global_thread_pool_spec.rb
99
101
  - spec/concurrent/goroutine_spec.rb
102
+ - spec/concurrent/null_thread_pool_spec.rb
100
103
  - spec/concurrent/obligation_shared.rb
101
104
  - spec/concurrent/promise_spec.rb
105
+ - spec/concurrent/reactor/drb_async_demux_spec.rb
106
+ - spec/concurrent/reactor/tcp_sync_demux_spec.rb
107
+ - spec/concurrent/reactor_spec.rb
102
108
  - spec/concurrent/smart_mutex_spec.rb
103
109
  - spec/concurrent/thread_pool_shared.rb
104
110
  - spec/concurrent/utilities_spec.rb
@@ -138,9 +144,14 @@ test_files:
138
144
  - spec/concurrent/fixed_thread_pool_spec.rb
139
145
  - spec/concurrent/functions_spec.rb
140
146
  - spec/concurrent/future_spec.rb
147
+ - spec/concurrent/global_thread_pool_spec.rb
141
148
  - spec/concurrent/goroutine_spec.rb
149
+ - spec/concurrent/null_thread_pool_spec.rb
142
150
  - spec/concurrent/obligation_shared.rb
143
151
  - spec/concurrent/promise_spec.rb
152
+ - spec/concurrent/reactor/drb_async_demux_spec.rb
153
+ - spec/concurrent/reactor/tcp_sync_demux_spec.rb
154
+ - spec/concurrent/reactor_spec.rb
144
155
  - spec/concurrent/smart_mutex_spec.rb
145
156
  - spec/concurrent/thread_pool_shared.rb
146
157
  - spec/concurrent/utilities_spec.rb
@@ -1,72 +0,0 @@
1
- require 'drb/drb'
2
- require 'drb/acl'
3
- require 'functional'
4
- require 'concurrent/reactor'
5
-
6
- module Concurrent
7
-
8
- class DRbAsyncDemux
9
-
10
- behavior(:async_event_demux)
11
-
12
- DEFAULT_URI = 'druby://localhost:12345'
13
- DEFAULT_ACL = %[allow all]
14
-
15
- def initialize(opts = {})
16
- @uri = opts[:uri] || DEFAULT_URI
17
- @acl = ACL.new(opts[:acl] || DEFAULT_ACL)
18
- end
19
-
20
- def set_reactor(reactor)
21
- raise ArgumentError.new('invalid reactor') unless reactor.behaves_as?(:demux_reactor)
22
- @reactor = reactor
23
- end
24
-
25
- def start
26
- DRb.install_acl(@acl)
27
- @service = DRb.start_service(@uri, Demultiplexer.new(@reactor))
28
- end
29
-
30
- def stop
31
- @service = DRb.stop_service
32
- end
33
-
34
- def stopped?
35
- return @service.nil?
36
- end
37
-
38
- private
39
-
40
- class Demultiplexer
41
-
42
- def initialize(reactor)
43
- @reactor = reactor
44
- end
45
-
46
- Concurrent::Reactor::RESERVED_EVENTS.each do |event|
47
- define_method(event){|*args| false }
48
- end
49
-
50
- def method_missing(method, *args, &block)
51
- (class << self; self; end).class_eval do
52
- define_method(method) do |*args|
53
- result = @reactor.handle(method, *args)
54
- case result.first
55
- when :ok
56
- return result.last
57
- when :ex
58
- raise result.last
59
- when :noop
60
- raise NoMethodError.new("undefined method '#{method}' for #{self}")
61
- else
62
- raise DRb::DRbUnknownError.new("unexpected error when calling method '#{method}'")
63
- end
64
- end
65
- end
66
- self.send(method, *args)
67
- end
68
- end
69
- end
70
-
71
- DRbAsyncDemultiplexer = DRbAsyncDemux
72
- end
@@ -1,96 +0,0 @@
1
- require 'socket'
2
- require 'drb/acl'
3
- require 'functional'
4
- require 'concurrent/reactor'
5
-
6
- module Concurrent
7
-
8
- class TcpSyncDemux
9
-
10
- behavior(:sync_event_demux)
11
-
12
- DEFAULT_HOST = '127.0.0.1'
13
- DEFAULT_PORT = 12345
14
- DEFAULT_ACL = %[allow all]
15
-
16
- def initialize(opts = {})
17
- @host = opts[:host] || DEFAULT_HOST
18
- @port = opts[:port] || DEFAULT_PORT
19
- @acl = ACL.new(opts[:acl] || DEFAULT_ACL)
20
- end
21
-
22
- def start
23
- @server = TCPServer.new(@host, @port)
24
- end
25
-
26
- def stop
27
- atomic {
28
- @socket.close unless @socket.nil?
29
- @server.close unless @server.nil?
30
- @server = @socket = nil
31
- }
32
- end
33
-
34
- def stopped?
35
- return @server.nil?
36
- end
37
-
38
- def accept
39
- @socket = @server.accept if @socket.nil?
40
- return nil unless @acl.allow_socket?(@socket)
41
- event, args = get_message(@socket)
42
- return nil if event.nil?
43
- return Reactor::EventContext.new(event, args)
44
- end
45
-
46
- def respond(result, message)
47
- return nil if @socket.nil?
48
- @socket.puts(format_message(result, message))
49
- end
50
-
51
- def close
52
- @socket.close
53
- @socket = nil
54
- end
55
-
56
- def self.format_message(event, *args)
57
- args = args.reduce('') do |memo, arg|
58
- memo << "#{arg}\r\n"
59
- end
60
- return ":#{event}\r\n#{args}\r\n"
61
- end
62
- def format_message(*args) self.class.format_message(*args); end
63
-
64
- def self.parse_message(message)
65
- return atomic {
66
- event = message.first.match /^:?(\w+)/
67
- event = event[1].to_s.downcase.to_sym unless event.nil?
68
-
69
- args = message.slice(1, message.length) || []
70
-
71
- [event, args]
72
- }
73
- end
74
- def parse_message(*args) self.class.parse_message(*args); end
75
-
76
- def self.get_message(socket)
77
- message = []
78
- while line = socket.gets
79
- if line.nil? || (line = line.strip).empty?
80
- break
81
- else
82
- message << line
83
- end
84
- end
85
-
86
- if message.empty?
87
- return nil
88
- else
89
- return parse_message(message)
90
- end
91
- end
92
- def get_message(*args) self.class.get_message(*args); end
93
- end
94
-
95
- TcpSyncDemultiplexer = TcpSyncDemux
96
- end