concurrent-ruby 0.4.0 → 0.4.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 755d47349aa9471448745d4d102eef30c9ff39f9
4
- data.tar.gz: 3ed64a6aa698387b8043cceb72bb64c3b45d4f2f
3
+ metadata.gz: 2a2299d64fb78b008f9f686ac6f72b87e92f54b5
4
+ data.tar.gz: b76068bdde155ed1e3f0572dca60b34cb9e7f952
5
5
  SHA512:
6
- metadata.gz: ba402eee86f4836735c7f659ac45c0c8df22863d718435179348a4fa5707a1671629d113c615ea4f87a0ac60019999556c1ae84b468c8abca3907e7e7efb6ea1
7
- data.tar.gz: a689c273e9173afffa0945b4621b88bd9276cf478c4aaf9692bddb78ed610521c9a22fb449ca229feb869654018f37df670f19eb172e027ba4a631f5482692ec
6
+ metadata.gz: cc3346484a3fce841b6e10ee5406bb938a8d16f48295b08fd71014187cf7adb24c398b6856aef6ad62ef74e6d13d5a4a5adc9b1a57102b5175eaf269256850fd
7
+ data.tar.gz: 8c30bbcfde894063c3c466dd7a66b13c30827674d13446dc0a9f95b46509c326913ca927303047bf7537971a49905c0286cd90a4e45788e89504277034ea5834
data/README.md CHANGED
@@ -41,9 +41,7 @@ The design goals of this gem are:
41
41
  ### Supported Ruby versions
42
42
 
43
43
  MRI 1.9.2, 1.9.3, 2.0, 2.1, and JRuby (1.9 mode). This library is pure Ruby and has no gem dependencies.
44
- It should be fully compatible with any Ruby interpreter that is 1.9.x compliant. I simply don't know enough
45
- about Rubinius or the others to fully support them. I can promise good karma and attribution on this page
46
- to anyone wishing to take responsibility for verifying compaitibility with any Ruby other than MRI.
44
+ It should be fully compatible with any Ruby interpreter that is 1.9.x compliant.
47
45
 
48
46
  ### Example
49
47
 
@@ -105,6 +103,21 @@ These tools will help ease the burden, but at the end of the day it is essential
105
103
  * Don't mix Ruby's [concurrency](http://ruby-doc.org/core-2.0.0/Thread.html)
106
104
  [primitives](http://www.ruby-doc.org/core-2.0.0/Mutex.html) with asynchronous concurrency libraries
107
105
 
106
+ ## Contributors
107
+
108
+ * [Michele Della Torre](https://github.com/mighe)
109
+ * [Chip Miller](https://github.com/chip-miller)
110
+ * [Jamie Hodge](https://github.com/jamiehodge)
111
+ * [Zander Hill](https://github.com/zph)
112
+
113
+ ## Contributing
114
+
115
+ 1. Fork it
116
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
117
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
118
+ 4. Push to the branch (`git push origin my-new-feature`)
119
+ 5. Create new Pull Request
120
+
108
121
  ### Conference Presentations
109
122
 
110
123
  I've given several conference presentations on concurrent programming with this gem.
@@ -123,39 +136,7 @@ Check them out:
123
136
  * I'll be giving ["Advanced Concurrent Programming in Ruby"](http://codemash.org/sessions)
124
137
  at [CodeMash 2014](http://codemash.org/)
125
138
 
126
- ## Contributing
127
-
128
- 1. Fork it
129
- 2. Create your feature branch (`git checkout -b my-new-feature`)
130
- 3. Commit your changes (`git commit -am 'Add some feature'`)
131
- 4. Push to the branch (`git push origin my-new-feature`)
132
- 5. Create new Pull Request
133
-
134
- ## Copyright
139
+ ## License and Copyright
135
140
 
136
141
  *Concurrent Ruby* is Copyright © 2013 [Jerry D'Antonio](https://twitter.com/jerrydantonio).
137
- It is free software and may be redistributed under the terms specified in the LICENSE file.
138
-
139
- ## License
140
-
141
- Released under the MIT license.
142
-
143
- http://www.opensource.org/licenses/mit-license.php
144
-
145
- > Permission is hereby granted, free of charge, to any person obtaining a copy
146
- > of this software and associated documentation files (the "Software"), to deal
147
- > in the Software without restriction, including without limitation the rights
148
- > to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
149
- > copies of the Software, and to permit persons to whom the Software is
150
- > furnished to do so, subject to the following conditions:
151
- >
152
- > The above copyright notice and this permission notice shall be included in
153
- > all copies or substantial portions of the Software.
154
- >
155
- > THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
156
- > IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
157
- > FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
158
- > AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
159
- > LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
160
- > OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
161
- > THE SOFTWARE.
142
+ It is free software released under the [MIT License](http://www.opensource.org/licenses/MIT).
@@ -21,6 +21,7 @@ require 'concurrent/global_thread_pool'
21
21
 
22
22
  require 'concurrent/cached_thread_pool'
23
23
  require 'concurrent/fixed_thread_pool'
24
+ require 'concurrent/immediate_executor'
24
25
 
25
26
  require 'concurrent/event_machine_defer_proxy' if defined?(EventMachine)
26
27
 
@@ -28,6 +28,7 @@ module Concurrent
28
28
  @rescuers = []
29
29
  @validator = nil
30
30
  @timeout = opts[:timeout] || TIMEOUT
31
+ init_mutex
31
32
  set_deref_options(opts)
32
33
  end
33
34
 
@@ -7,6 +7,7 @@ module Concurrent
7
7
 
8
8
  def initialize(opts = {})
9
9
  @state = :pending
10
+ init_mutex
10
11
  set_deref_options(opts)
11
12
  end
12
13
 
@@ -21,8 +21,8 @@ module Concurrent
21
21
  # returning the value returned from the proc (default: `nil`)
22
22
  def set_deref_options(opts = {})
23
23
  mutex.synchronize do
24
- @dup_on_deref = opts[:dup_on_deref] || opts[:dup] || false
25
- @freeze_on_deref = opts[:freeze_on_deref] || opts[:freeze] || false
24
+ @dup_on_deref = opts[:dup_on_deref] || opts[:dup]
25
+ @freeze_on_deref = opts[:freeze_on_deref] || opts[:freeze]
26
26
  @copy_on_deref = opts[:copy_on_deref] || opts[:copy]
27
27
  @do_nothing_on_deref = ! (@dup_on_deref || @freeze_on_deref || @copy_on_deref)
28
28
  end
@@ -33,7 +33,7 @@ module Concurrent
33
33
  def value
34
34
  return nil if @value.nil?
35
35
  return @value if @do_nothing_on_deref
36
- return mutex.synchronize do
36
+ mutex.synchronize do
37
37
  value = @value
38
38
  value = @copy_on_deref.call(value) if @copy_on_deref
39
39
  value = value.dup if @dup_on_deref
@@ -45,9 +45,12 @@ module Concurrent
45
45
 
46
46
  protected
47
47
 
48
- # @private
49
48
  def mutex # :nodoc:
50
- @mutex ||= Mutex.new
49
+ @mutex
50
+ end
51
+
52
+ def init_mutex
53
+ @mutex = Mutex.new
51
54
  end
52
55
  end
53
56
  end
@@ -20,14 +20,16 @@ module Concurrent
20
20
  def initialize
21
21
  @set = false
22
22
  @mutex = Mutex.new
23
- @waiters = []
23
+ @condition = ConditionVariable.new
24
24
  end
25
25
 
26
26
  # Is the object in the set state?
27
27
  #
28
28
  # @return [Boolean] indicating whether or not the `Event` has been set
29
29
  def set?
30
- return @set == true
30
+ @mutex.synchronize do
31
+ @set
32
+ end
31
33
  end
32
34
 
33
35
  # Trigger the event, setting the state to `set` and releasing all threads
@@ -35,12 +37,13 @@ module Concurrent
35
37
  #
36
38
  # @return [Boolean] should always return `true`
37
39
  def set
38
- return true if set?
39
40
  @mutex.synchronize do
41
+ return true if @set
40
42
  @set = true
41
- @waiters.each {|waiter| waiter.run if waiter.status == 'sleep'}
43
+ @condition.broadcast
42
44
  end
43
- return true
45
+
46
+ true
44
47
  end
45
48
 
46
49
  # Reset a previously set event back to the `unset` state.
@@ -48,12 +51,11 @@ module Concurrent
48
51
  #
49
52
  # @return [Boolean] should always return `true`
50
53
  def reset
51
- return true unless set?
52
54
  @mutex.synchronize do
53
55
  @set = false
54
- @waiters.clear # just in case there's garbage
55
56
  end
56
- return true
57
+
58
+ true
57
59
  end
58
60
 
59
61
  # Wait a given number of seconds for the `Event` to be set by another
@@ -62,21 +64,11 @@ module Concurrent
62
64
  #
63
65
  # @return [Boolean] true if the `Event` was set before timeout else false
64
66
  def wait(timeout = nil)
65
- return true if set?
66
-
67
- @mutex.synchronize { @waiters << Thread.current }
68
- return true if set? # if event was set while waiting for mutex
69
-
70
- if timeout.nil?
71
- slept = sleep
72
- else
73
- slept = sleep(timeout)
67
+ @mutex.synchronize do
68
+ return true if @set
69
+ @condition.wait(@mutex, timeout)
70
+ @set
74
71
  end
75
- rescue
76
- # let it fail
77
- ensure
78
- @mutex.synchronize { @waiters.delete(Thread.current) }
79
- return set?
80
72
  end
81
73
  end
82
74
  end
@@ -12,6 +12,7 @@ module Concurrent
12
12
  include UsesGlobalThreadPool
13
13
 
14
14
  def initialize(*args, &block)
15
+ init_mutex
15
16
  unless block_given?
16
17
  @state = :fulfilled
17
18
  else
@@ -0,0 +1,14 @@
1
+ module Concurrent
2
+ class ImmediateExecutor
3
+
4
+ def post(*args, &block)
5
+ block.call(*args)
6
+ end
7
+
8
+ def <<(block)
9
+ post(&block)
10
+ self
11
+ end
12
+
13
+ end
14
+ end
@@ -41,6 +41,7 @@ module Concurrent
41
41
  @children = []
42
42
  @rescuers = []
43
43
 
44
+ init_mutex
44
45
  realize(*args) if root?
45
46
  end
46
47
 
@@ -29,6 +29,7 @@ module Concurrent
29
29
  @state = :pending
30
30
  @schedule_time.freeze
31
31
  @task = block
32
+ init_mutex
32
33
  set_deref_options(opts)
33
34
 
34
35
  @thread = Thread.new{ work }
@@ -198,6 +198,7 @@ module Concurrent
198
198
  @run_now = opts[:now] || opts[:run_now] || false
199
199
 
200
200
  @task = block
201
+ init_mutex
201
202
  set_deref_options(opts)
202
203
  end
203
204
 
@@ -1,3 +1,3 @@
1
1
  module Concurrent
2
- VERSION = '0.4.0'
2
+ VERSION = '0.4.1'
3
3
  end
@@ -268,7 +268,7 @@ pool.each{|actor| overlord.add_worker(actor)}
268
268
 
269
269
  overlord.run!
270
270
 
271
- pool.post('YAHOO')
271
+ financial.post('YAHOO')
272
272
 
273
273
  #>> [2013-10-18 09:35:28 -0400] SENT 'YAHOO' from main to worker pool
274
274
  #>> [2013-10-18 09:35:28 -0400] RECEIVED 'YAHOO' to #<FinanceActor:0x0000010331af70>...
@@ -58,36 +58,37 @@ module Concurrent
58
58
 
59
59
  context 'fulfillment' do
60
60
 
61
+ before(:each) do
62
+ Future.thread_pool = ImmediateExecutor.new
63
+ end
64
+
61
65
  it 'passes all arguments to handler' do
62
- @a = @b = @c = nil
63
- f = Future.new(1, 2, 3) do |a, b, c|
64
- @a, @b, @c = a, b, c
66
+ result = nil
67
+
68
+ Future.new(1, 2, 3) do |a, b, c|
69
+ result = [a, b, c]
65
70
  end
66
- sleep(0.1)
67
- [@a, @b, @c].should eq [1, 2, 3]
71
+
72
+ result.should eq [1, 2, 3]
68
73
  end
69
74
 
70
75
  it 'sets the value to the result of the handler' do
71
76
  f = Future.new(10){|a| a * 2 }
72
- sleep(0.1)
73
77
  f.value.should eq 20
74
78
  end
75
79
 
76
80
  it 'sets the state to :fulfilled when the block completes' do
77
81
  f = Future.new(10){|a| a * 2 }
78
- sleep(0.1)
79
82
  f.should be_fulfilled
80
83
  end
81
84
 
82
85
  it 'sets the value to nil when the handler raises an exception' do
83
86
  f = Future.new{ raise StandardError }
84
- sleep(0.1)
85
87
  f.value.should be_nil
86
88
  end
87
89
 
88
90
  it 'sets the state to :rejected when the handler raises an exception' do
89
91
  f = Future.new{ raise StandardError }
90
- sleep(0.1)
91
92
  f.should be_rejected
92
93
  end
93
94
 
@@ -0,0 +1,33 @@
1
+ require 'spec_helper'
2
+
3
+ module Concurrent
4
+
5
+ describe ImmediateExecutor do
6
+
7
+ let(:executor) { ImmediateExecutor.new }
8
+
9
+ context "#post" do
10
+ it 'executes the block using the arguments as parameters' do
11
+ result = executor.post(1, 2, 3, 4) { |a, b, c, d| [a, b, c, d] }
12
+ result.should eq [1, 2, 3, 4]
13
+ end
14
+ end
15
+
16
+ context "#<<" do
17
+
18
+ it "returns true" do
19
+ result = executor << proc { false }
20
+ result.should be_true
21
+ end
22
+
23
+ it "executes the passed callable" do
24
+ x = 0
25
+
26
+ executor << proc { x = 5 }
27
+
28
+ x.should eq 5
29
+ end
30
+
31
+ end
32
+ end
33
+ end
metadata CHANGED
@@ -1,29 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: concurrent-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.4.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-01-07 00:00:00.000000000 Z
12
- dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: bundler
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - ">="
18
- - !ruby/object:Gem::Version
19
- version: '0'
20
- type: :development
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - ">="
25
- - !ruby/object:Gem::Version
26
- version: '0'
11
+ date: 2014-02-03 00:00:00.000000000 Z
12
+ dependencies: []
27
13
  description: |2
28
14
  Modern concurrency tools including agents, futures, promises, thread pools, actors, supervisors, and more.
29
15
  Inspired by Erlang, Clojure, Go, JavaScript, actors, and classic concurrency patterns.
@@ -50,6 +36,7 @@ files:
50
36
  - lib/concurrent/fixed_thread_pool/worker.rb
51
37
  - lib/concurrent/future.rb
52
38
  - lib/concurrent/global_thread_pool.rb
39
+ - lib/concurrent/immediate_executor.rb
53
40
  - lib/concurrent/obligation.rb
54
41
  - lib/concurrent/postable.rb
55
42
  - lib/concurrent/promise.rb
@@ -82,6 +69,7 @@ files:
82
69
  - spec/concurrent/fixed_thread_pool_spec.rb
83
70
  - spec/concurrent/future_spec.rb
84
71
  - spec/concurrent/global_thread_pool_spec.rb
72
+ - spec/concurrent/immediate_executor_spec.rb
85
73
  - spec/concurrent/obligation_shared.rb
86
74
  - spec/concurrent/postable_shared.rb
87
75
  - spec/concurrent/promise_spec.rb
@@ -100,26 +88,23 @@ homepage: http://www.concurrent-ruby.com
100
88
  licenses:
101
89
  - MIT
102
90
  metadata: {}
103
- post_install_message: |2
104
- future = Concurrent::Future.new{ 'Hello, world!' }
105
- puts future.value
106
- #=> Hello, world!
91
+ post_install_message:
107
92
  rdoc_options: []
108
93
  require_paths:
109
94
  - lib
110
95
  required_ruby_version: !ruby/object:Gem::Requirement
111
96
  requirements:
112
- - - ">="
97
+ - - '>='
113
98
  - !ruby/object:Gem::Version
114
99
  version: 1.9.2
115
100
  required_rubygems_version: !ruby/object:Gem::Requirement
116
101
  requirements:
117
- - - ">="
102
+ - - '>='
118
103
  - !ruby/object:Gem::Version
119
104
  version: '0'
120
105
  requirements: []
121
106
  rubyforge_project:
122
- rubygems_version: 2.2.0.rc.1
107
+ rubygems_version: 2.2.1
123
108
  signing_key:
124
109
  specification_version: 4
125
110
  summary: Modern concurrency tools including agents, futures, promises, thread pools,
@@ -135,6 +120,7 @@ test_files:
135
120
  - spec/concurrent/fixed_thread_pool_spec.rb
136
121
  - spec/concurrent/future_spec.rb
137
122
  - spec/concurrent/global_thread_pool_spec.rb
123
+ - spec/concurrent/immediate_executor_spec.rb
138
124
  - spec/concurrent/obligation_shared.rb
139
125
  - spec/concurrent/postable_shared.rb
140
126
  - spec/concurrent/promise_spec.rb