concurrent-ruby 1.0.3 → 1.0.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: faedca437c0657830f5b0cf420bbc9fe8a7f9908
4
- data.tar.gz: 26114b1a172fdff0a590694d0c417a9ae3e52b5e
3
+ metadata.gz: 1f2057bba5c491730f2195150ad50cf4d2602143
4
+ data.tar.gz: ae0f81c1ca1b860e59d751df021389fac61ad736
5
5
  SHA512:
6
- metadata.gz: ded8d7abaf69a21931f850de692e0b8e34bbd3275ff294a3afe7f3697dd52e3a638a6359f0c5a8ab7b8d60beaecbf9bfc2469868e4a45629c22678975c42f8c8
7
- data.tar.gz: 2d9b104c2c7eeb3352aa78dddf6a0c3a1b46752d973409a443cd6b53ed64a948378290a88fbb83a9d292ab12c649deac86a05c1fff5ad51f39169afba9e65673
6
+ metadata.gz: 2ad27004cc16860bbd15debd5a3ad1b0da3fb3ee2d568f9db428d4eef434ae5e2444548754775ce22dbc820636591e41ce0324a2475acf2e7eb8e9e4bb2e7927
7
+ data.tar.gz: f6e90a9735aa4ce2bade9754ea15bce067035644658980f24196c9e6cac5b3d9415cb3e0f42206192c58989c3cdebe5fc4b31b978fb4e546dd7fc34f0049da63
@@ -1,3 +1,17 @@
1
+ ## Current Release v1.0.4 (27 Dec 2016)
2
+
3
+ concurrent-ruby:
4
+
5
+ * Nothing
6
+
7
+ concurrent-ruby-edge:
8
+
9
+ * New promises' API renamed, lots of improvements, edge bumped to 0.3.0
10
+ * **Incompatible** with previous 0.2.3 version
11
+ * see https://github.com/ruby-concurrency/concurrent-ruby/pull/522
12
+
13
+ ## Release v1.0.3 (17 Dec 2016)
14
+
1
15
  * Trigger execution of flattened delayed futures
2
16
  * Avoid forking for processor_count if possible
3
17
  * Semaphore Mutex and JRuby parity
@@ -12,14 +26,14 @@
12
26
  * Fixes format-security error when compiling ruby_193_compatible.h
13
27
  * Concurrent::Atom#swap fixed: reraise the exceptions from block
14
28
 
15
- ## Current Release v1.0.2 (2 May 2016)
29
+ ## Release v1.0.2 (2 May 2016)
16
30
 
17
31
  * Fix bug with `Concurrent::Map` MRI backend `#inspect` method
18
32
  * Fix bug with `Concurrent::Map` MRI backend using `Hash#value?`
19
33
  * Improved documentation and examples
20
34
  * Minor updates to Edge
21
35
 
22
- ### Release v1.0.1 (27 February 2016)
36
+ ## Release v1.0.1 (27 February 2016)
23
37
 
24
38
  * Fix "uninitialized constant Concurrent::ReentrantReadWriteLock" error.
25
39
  * Better handling of `autoload` vs. `require`.
@@ -32,7 +46,7 @@
32
46
  * Improved documentation.
33
47
  * Updated README and CONTRIBUTING.
34
48
 
35
- ### Release v1.0.0 (13 November 2015)
49
+ ## Release v1.0.0 (13 November 2015)
36
50
 
37
51
  * Rename `attr_volatile_with_cas` to `attr_atomic`
38
52
  * Add `clear_each` to `LockFreeStack`
@@ -80,7 +94,7 @@
80
94
  * Many improved tests
81
95
  * Some internal reorganization
82
96
 
83
- ### Release v0.9.1 (09 August 2015)
97
+ ## Release v0.9.1 (09 August 2015)
84
98
 
85
99
  * Fixed a Rubiniux bug in synchronization object
86
100
  * Fixed all interpreter warnings (except circular references)
@@ -94,7 +108,7 @@
94
108
  * `ThreadLocalVar#bind` method is now public
95
109
  * Refactored many tests
96
110
 
97
- ### Release v0.9.0 (10 July 2015)
111
+ ## Release v0.9.0 (10 July 2015)
98
112
 
99
113
  * Updated `AtomicReference`
100
114
  - `AtomicReference#try_update` now simply returns instead of raising exception
@@ -193,14 +207,14 @@
193
207
  * Removed brute-force killing of threads in tests
194
208
  * Fixed a thread pool bug when the operating system cannot allocate more threads
195
209
 
196
- ### Release v0.8.0 (25 January 2015)
210
+ ## Release v0.8.0 (25 January 2015)
197
211
 
198
212
  * C extension for MRI have been extracted into the `concurrent-ruby-ext` companion gem.
199
213
  Please see the README for more detail.
200
214
  * Better variable isolation in `Promise` and `Future` via an `:args` option
201
215
  * Continued to update intermittently failing tests
202
216
 
203
- ### Release v0.7.2 (24 January 2015)
217
+ ## Release v0.7.2 (24 January 2015)
204
218
 
205
219
  * New `Semaphore` class based on [java.util.concurrent.Semaphore](http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Semaphore.html)
206
220
  * New `Promise.all?` and `Promise.any?` class methods
@@ -217,7 +231,7 @@
217
231
  * Tests now run on new Travis build environment
218
232
  * Multiple documentation updates
219
233
 
220
- ### Release v0.7.1 (4 December 2014)
234
+ ## Release v0.7.1 (4 December 2014)
221
235
 
222
236
  Please see the [roadmap](https://github.com/ruby-concurrency/concurrent-ruby/issues/142) for more information on the next planned release.
223
237
 
@@ -238,7 +252,7 @@ Please see the [roadmap](https://github.com/ruby-concurrency/concurrent-ruby/iss
238
252
  * Removed confusing warning when not using native extenstions
239
253
  * Improved documentation
240
254
 
241
- ### Release v0.7.0 (13 August 2014)
255
+ ## Release v0.7.0 (13 August 2014)
242
256
 
243
257
  * Merge the [atomic](https://github.com/ruby-concurrency/atomic) gem
244
258
  - Pure Ruby `MutexAtomic` atomic reference class
@@ -271,14 +285,14 @@ Please see the [roadmap](https://github.com/ruby-concurrency/concurrent-ruby/iss
271
285
  * Removed deprecated `Actor` class
272
286
  * Better support for Rubinius
273
287
 
274
- ### Release v0.6.1 (14 June 2014)
288
+ ## Release v0.6.1 (14 June 2014)
275
289
 
276
290
  * Many improvements to `Concurrent::Actress`
277
291
  * Bug fixes to `Concurrent::RubyThreadPoolExecutor`
278
292
  * Fixed several brittle tests
279
293
  * Moved documentation to http://ruby-concurrency.github.io/concurrent-ruby/frames.html
280
294
 
281
- ### Release v0.6.0 (25 May 2014)
295
+ ## Release v0.6.0 (25 May 2014)
282
296
 
283
297
  * Added `Concurrent::Observable` to encapsulate our thread safe observer sets
284
298
  * Improvements to new `Channel`
@@ -317,7 +331,7 @@ Please see the [roadmap](https://github.com/ruby-concurrency/concurrent-ruby/iss
317
331
  * First implementation of [new, high-performance](https://github.com/ruby-concurrency/concurrent-ruby/pull/49) `Channel`
318
332
  * `Actor` is deprecated in favor of new experimental actor implementation [#73](https://github.com/ruby-concurrency/concurrent-ruby/pull/73). To avoid namespace collision it is living in `Actress` namespace until `Actor` is removed in next release.
319
333
 
320
- ### Release v0.5.0
334
+ ## Release v0.5.0
321
335
 
322
336
  This is the most significant release of this gem since its inception. This release includes many improvements and optimizations. It also includes several bug fixes. The major areas of focus for this release were:
323
337
 
data/README.md CHANGED
@@ -9,39 +9,28 @@
9
9
  [![License](https://img.shields.io/badge/license-MIT-green.svg)](http://opensource.org/licenses/MIT)
10
10
  [![Gitter chat](https://img.shields.io/badge/IRC%20(gitter)-devs%20%26%20users-brightgreen.svg)](https://gitter.im/ruby-concurrency/concurrent-ruby)
11
11
 
12
- <table>
13
- <tr>
14
- <td align="left" valign="top">
15
- <p>
16
- Modern concurrency tools for Ruby. Inspired by
17
- <a href="http://www.erlang.org/doc/reference_manual/processes.html">Erlang</a>,
18
- <a href="http://clojure.org/concurrent_programming">Clojure</a>,
19
- <a href="http://akka.io/">Scala</a>,
20
- <a href="http://www.haskell.org/haskellwiki/Applications_and_libraries/Concurrency_and_parallelism#Concurrent_Haskell">Haskell</a>,
21
- <a href="http://blogs.msdn.com/b/dsyme/archive/2010/02/15/async-and-parallel-design-patterns-in-f-part-3-agents.aspx">F#</a>,
22
- <a href="http://msdn.microsoft.com/en-us/library/vstudio/hh191443.aspx">C#</a>,
23
- <a href="http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/package-summary.html">Java</a>,
24
- and classic concurrency patterns.
25
- </p>
26
- <p>
27
- The design goals of this gem are:
28
- <ul>
29
- <li>Be an 'unopinionated' toolbox that provides useful utilities without debating which is better or why</li>
30
- <li>Remain free of external gem dependencies</li>
31
- <li>Stay true to the spirit of the languages providing inspiration</li>
32
- <li>But implement in a way that makes sense for Ruby</li>
33
- <li>Keep the semantics as idiomatic Ruby as possible</li>
34
- <li>Support features that make sense in Ruby</li>
35
- <li>Exclude features that don't make sense in Ruby</li>
36
- <li>Be small, lean, and loosely coupled</li>
37
- </ul>
38
- </p>
39
- </td>
40
- <td align="right" valign="top">
41
- <img src="https://raw.githubusercontent.com/ruby-concurrency/concurrent-ruby/master/doc/logo/concurrent-ruby-logo-300x300.png"/>
42
- </td>
43
- </tr>
44
- </table>
12
+ Modern concurrency tools for Ruby. Inspired by
13
+ [Erlang](http://www.erlang.org/doc/reference_manual/processes.html),
14
+ [Clojure](http://clojure.org/concurrent_programming),
15
+ [Scala](http://akka.io/),
16
+ [Haskell](http://www.haskell.org/haskellwiki/Applications_and_libraries/Concurrency_and_parallelism#Concurrent_Haskell),
17
+ [F#](http://blogs.msdn.com/b/dsyme/archive/2010/02/15/async-and-parallel-design-patterns-in-f-part-3-agents.aspx),
18
+ [C#](http://msdn.microsoft.com/en-us/library/vstudio/hh191443.aspx),
19
+ [Java](http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/package-summary.html),
20
+ and classic concurrency patterns.
21
+
22
+ <img src="https://raw.githubusercontent.com/ruby-concurrency/concurrent-ruby/master/doc/logo/concurrent-ruby-logo-300x300.png" align="right" style="margin-left: 20px;" />
23
+
24
+ The design goals of this gem are:
25
+
26
+ * Be an 'unopinionated' toolbox that provides useful utilities without debating which is better or why
27
+ * Remain free of external gem dependencies
28
+ * Stay true to the spirit of the languages providing inspiration
29
+ * But implement in a way that makes sense for Ruby
30
+ * Keep the semantics as idiomatic Ruby as possible
31
+ * Support features that make sense in Ruby
32
+ * Exclude features that don't make sense in Ruby
33
+ * Be small, lean, and loosely coupled
45
34
 
46
35
  ### Supported Ruby versions
47
36
 
@@ -127,13 +116,13 @@ These features are under active development and may change frequently. They are
127
116
  keep backward compatibility (there may also lack tests and documentation). Semantic versions will
128
117
  be obeyed though. Features developed in `concurrent-ruby-edge` are expected to move to `concurrent-ruby` when final.
129
118
 
130
- * [Actor](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Actor.html):
131
- Implements the Actor Model, where concurrent actors exchange messages.
132
- * [New Future Framework](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Edge/FutureShortcuts.html):
119
+ * [Promises Framework](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Promises.html):
133
120
  Unified implementation of futures and promises which combines features of previous `Future`,
134
121
  `Promise`, `IVar`, `Event`, `dataflow`, `Delay`, and `TimerTask` into a single framework. It extensively uses the
135
122
  new synchronization layer to make all the features **non-blocking** and **lock-free**, with the exception of obviously blocking
136
123
  operations like `#wait`, `#value`. It also offers better performance.
124
+ * [Actor](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Actor.html):
125
+ Implements the Actor Model, where concurrent actors exchange messages.
137
126
  * [Channel](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Edge/Channel.html):
138
127
  Communicating Sequential Processes ([CSP](https://en.wikipedia.org/wiki/Communicating_sequential_processes)).
139
128
  Functionally equivalent to Go [channels](https://tour.golang.org/concurrency/2) with additional
@@ -141,15 +130,16 @@ be obeyed though. Features developed in `concurrent-ruby-edge` are expected to m
141
130
  * [LazyRegister](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/LazyRegister.html)
142
131
  * [AtomicMarkableReference](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Edge/AtomicMarkableReference.html)
143
132
  * [LockFreeLinkedSet](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Edge/LockFreeLinkedSet.html)
144
- * [LockFreeStack](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Edge/LockFreeStack.html)
133
+ * [LockFreeStack](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/LockFreeStack.html)
145
134
 
146
135
  #### Statuses:
147
136
 
148
137
  *Why are these not in core?*
149
138
 
139
+ - **Promises Framework** - They are being finalized to be able to be moved to core. They'll deprecate old
140
+ implementation.
150
141
  - **Actor** - Partial documentation and tests; depends on new future/promise framework; stability is good.
151
142
  - **Channel** - Brand new implementation; partial documentation and tests; stability is good.
152
- - **Future/Promise Framework** - API changes; partial documentation and tests; stability is good.
153
143
  - **LazyRegister** - Missing documentation and tests.
154
144
  - **AtomicMarkableReference, LockFreeLinkedSet, LockFreeStack** - Need real world battle testing.
155
145
 
@@ -37,6 +37,7 @@ require 'concurrent/synchronization'
37
37
  # *coordinated*, *synchronous*, change of *many* stated. Used when multiple
38
38
  # value must change together, in an all-or-nothing transaction.
39
39
 
40
+
40
41
  module Concurrent
41
42
 
42
43
  # Atoms provide a way to manage shared, synchronous, independent state.
@@ -129,5 +129,9 @@ module Concurrent
129
129
  #
130
130
  # @!macro atomic_fixnum_public_api
131
131
  class AtomicFixnum < AtomicFixnumImplementation
132
+ # @return [String] Short string representation.
133
+ def to_s
134
+ format '<#%s:0x%x value:%s>', self.class, object_id << 1, get
135
+ end
132
136
  end
133
137
  end
@@ -40,3 +40,10 @@ else
40
40
  class Concurrent::AtomicReference < Concurrent::MutexAtomicReference
41
41
  end
42
42
  end
43
+
44
+ class Concurrent::AtomicReference
45
+ # @return [String] Short string representation.
46
+ def to_s
47
+ format '<#%s:0x%x value:%s>', self.class, object_id << 1, get
48
+ end
49
+ end
@@ -29,8 +29,8 @@ module Concurrent
29
29
  # array, so we don't leak memory
30
30
 
31
31
  # @!visibility private
32
- FREE = []
33
- LOCK = Mutex.new
32
+ FREE = []
33
+ LOCK = Mutex.new
34
34
  ARRAYS = {} # used as a hash set
35
35
  @@next = 0
36
36
  private_constant :FREE, :LOCK, :ARRAYS
@@ -72,9 +72,9 @@ module Concurrent
72
72
  def allocate_storage
73
73
  @index = LOCK.synchronize do
74
74
  FREE.pop || begin
75
- result = @@next
76
- @@next += 1
77
- result
75
+ result = @@next
76
+ @@next += 1
77
+ result
78
78
  end
79
79
  end
80
80
  ObjectSpace.define_finalizer(self, self.class.threadlocal_finalizer(@index))
@@ -83,13 +83,15 @@ module Concurrent
83
83
  # @!visibility private
84
84
  def self.threadlocal_finalizer(index)
85
85
  proc do
86
- LOCK.synchronize do
87
- FREE.push(index)
88
- # The cost of GC'ing a TLV is linear in the number of threads using TLVs
89
- # But that is natural! More threads means more storage is used per TLV
90
- # So naturally more CPU time is required to free more storage
91
- ARRAYS.each_value do |array|
92
- array[index] = nil
86
+ Thread.new do # avoid error: can't be called from trap context
87
+ LOCK.synchronize do
88
+ FREE.push(index)
89
+ # The cost of GC'ing a TLV is linear in the number of threads using TLVs
90
+ # But that is natural! More threads means more storage is used per TLV
91
+ # So naturally more CPU time is required to free more storage
92
+ ARRAYS.each_value do |array|
93
+ array[index] = nil
94
+ end
93
95
  end
94
96
  end
95
97
  end
@@ -98,10 +100,12 @@ module Concurrent
98
100
  # @!visibility private
99
101
  def self.thread_finalizer(array)
100
102
  proc do
101
- LOCK.synchronize do
102
- # The thread which used this thread-local array is now gone
103
- # So don't hold onto a reference to the array (thus blocking GC)
104
- ARRAYS.delete(array.object_id)
103
+ Thread.new do # avoid error: can't be called from trap context
104
+ LOCK.synchronize do
105
+ # The thread which used this thread-local array is now gone
106
+ # So don't hold onto a reference to the array (thus blocking GC)
107
+ ARRAYS.delete(array.object_id)
108
+ end
105
109
  end
106
110
  end
107
111
  end
@@ -11,7 +11,7 @@ module Concurrent
11
11
  # Creates a thread local variable.
12
12
  #
13
13
  # @param [Object] default the default value when otherwise unset
14
- # @param [Proc] block Optional block that gets called to obtain the
14
+ # @param [Proc] default_block Optional block that gets called to obtain the
15
15
  # default value for each thread
16
16
 
17
17
  # @!macro [new] thread_local_var_method_get
@@ -72,28 +72,28 @@ module Concurrent
72
72
  # the current thread will ever see that change.
73
73
  #
74
74
  # @!macro thread_safe_variable_comparison
75
- #
75
+ #
76
76
  # @example
77
77
  # v = ThreadLocalVar.new(14)
78
78
  # v.value #=> 14
79
79
  # v.value = 2
80
80
  # v.value #=> 2
81
- #
81
+ #
82
82
  # @example
83
83
  # v = ThreadLocalVar.new(14)
84
- #
84
+ #
85
85
  # t1 = Thread.new do
86
86
  # v.value #=> 14
87
87
  # v.value = 1
88
88
  # v.value #=> 1
89
89
  # end
90
- #
90
+ #
91
91
  # t2 = Thread.new do
92
92
  # v.value #=> 14
93
93
  # v.value = 2
94
94
  # v.value #=> 2
95
95
  # end
96
- #
96
+ #
97
97
  # v.value #=> 14
98
98
  #
99
99
  # @see https://docs.oracle.com/javase/7/docs/api/java/lang/ThreadLocal.html Java ThreadLocal
@@ -1 +1,2 @@
1
- require 'concurrent/atomic_reference/mutex_atomic'
1
+ require 'atomic'
2
+ require 'concurrent/atomic_reference/rbx'
@@ -95,6 +95,7 @@ module Concurrent
95
95
  end
96
96
 
97
97
  def each_pair
98
+ return enum_for :each_pair unless block_given?
98
99
  dupped_backend.each_pair do |k, v|
99
100
  yield k, v
100
101
  end
@@ -10,11 +10,43 @@ require 'concurrent/utility/processor_counter'
10
10
  module Concurrent
11
11
  extend Concern::Logging
12
12
 
13
- autoload :Options, 'concurrent/options'
14
- autoload :TimerSet, 'concurrent/executor/timer_set'
13
+ autoload :Options, 'concurrent/options'
14
+ autoload :TimerSet, 'concurrent/executor/timer_set'
15
15
  autoload :ThreadPoolExecutor, 'concurrent/executor/thread_pool_executor'
16
16
 
17
17
  # @return [Logger] Logger with provided level and output.
18
+ def self.create_simple_logger(level = Logger::FATAL, output = $stderr)
19
+ # TODO (pitr-ch 24-Dec-2016): figure out why it had to be replaced, stdlogger was deadlocking
20
+ lambda do |severity, progname, message = nil, &block|
21
+ return false if severity < level
22
+
23
+ message = block ? block.call : message
24
+ formatted_message = case message
25
+ when String
26
+ message
27
+ when Exception
28
+ format "%s (%s)\n%s",
29
+ message.message, message.class, (message.backtrace || []).join("\n")
30
+ else
31
+ message.inspect
32
+ end
33
+
34
+ output.print format "[%s] %5s -- %s: %s\n",
35
+ Time.now.strftime('%Y-%m-%d %H:%M:%S.%L'),
36
+ Logger::SEV_LABEL[severity],
37
+ progname,
38
+ formatted_message
39
+ true
40
+ end
41
+ end
42
+
43
+ # Use logger created by #create_simple_logger to log concurrent-ruby messages.
44
+ def self.use_simple_logger(level = Logger::FATAL, output = $stderr)
45
+ Concurrent.global_logger = create_simple_logger level, output
46
+ end
47
+
48
+ # @return [Logger] Logger with provided level and output.
49
+ # @deprecated
18
50
  def self.create_stdlib_logger(level = Logger::FATAL, output = $stderr)
19
51
  logger = Logger.new(output)
20
52
  logger.level = level
@@ -24,32 +56,35 @@ module Concurrent
24
56
  msg
25
57
  when Exception
26
58
  format "%s (%s)\n%s",
27
- msg.message, msg.class, (msg.backtrace || []).join("\n")
59
+ msg.message, msg.class, (msg.backtrace || []).join("\n")
28
60
  else
29
61
  msg.inspect
30
62
  end
31
63
  format "[%s] %5s -- %s: %s\n",
32
- datetime.strftime('%Y-%m-%d %H:%M:%S.%L'),
33
- severity,
34
- progname,
35
- formatted_message
64
+ datetime.strftime('%Y-%m-%d %H:%M:%S.%L'),
65
+ severity,
66
+ progname,
67
+ formatted_message
36
68
  end
37
69
 
38
70
  lambda do |loglevel, progname, message = nil, &block|
39
- logger.add loglevel, message, progname, &block
71
+ logger.add loglevel, message, progname, &block
40
72
  end
41
73
  end
42
74
 
43
75
  # Use logger created by #create_stdlib_logger to log concurrent-ruby messages.
76
+ # @deprecated
44
77
  def self.use_stdlib_logger(level = Logger::FATAL, output = $stderr)
45
78
  Concurrent.global_logger = create_stdlib_logger level, output
46
79
  end
47
80
 
81
+ # TODO (pitr-ch 27-Dec-2016): remove deadlocking stdlib_logger methods
82
+
48
83
  # Suppresses all output when used for logging.
49
84
  NULL_LOGGER = lambda { |level, progname, message = nil, &block| }
50
85
 
51
86
  # @!visibility private
52
- GLOBAL_LOGGER = AtomicReference.new(create_stdlib_logger(Logger::WARN))
87
+ GLOBAL_LOGGER = AtomicReference.new(create_simple_logger(Logger::WARN))
53
88
  private_constant :GLOBAL_LOGGER
54
89
 
55
90
  def self.global_logger
@@ -131,23 +166,23 @@ module Concurrent
131
166
 
132
167
  def self.new_fast_executor(opts = {})
133
168
  FixedThreadPool.new(
134
- [2, Concurrent.processor_count].max,
135
- auto_terminate: opts.fetch(:auto_terminate, true),
136
- idletime: 60, # 1 minute
137
- max_queue: 0, # unlimited
138
- fallback_policy: :abort # shouldn't matter -- 0 max queue
169
+ [2, Concurrent.processor_count].max,
170
+ auto_terminate: opts.fetch(:auto_terminate, true),
171
+ idletime: 60, # 1 minute
172
+ max_queue: 0, # unlimited
173
+ fallback_policy: :abort # shouldn't matter -- 0 max queue
139
174
  )
140
175
  end
141
176
 
142
177
  def self.new_io_executor(opts = {})
143
178
  ThreadPoolExecutor.new(
144
- min_threads: [2, Concurrent.processor_count].max,
145
- max_threads: ThreadPoolExecutor::DEFAULT_MAX_POOL_SIZE,
146
- # max_threads: 1000,
147
- auto_terminate: opts.fetch(:auto_terminate, true),
148
- idletime: 60, # 1 minute
149
- max_queue: 0, # unlimited
150
- fallback_policy: :abort # shouldn't matter -- 0 max queue
179
+ min_threads: [2, Concurrent.processor_count].max,
180
+ max_threads: ThreadPoolExecutor::DEFAULT_MAX_POOL_SIZE,
181
+ # max_threads: 1000,
182
+ auto_terminate: opts.fetch(:auto_terminate, true),
183
+ idletime: 60, # 1 minute
184
+ max_queue: 0, # unlimited
185
+ fallback_policy: :abort # shouldn't matter -- 0 max queue
151
186
  )
152
187
  end
153
188
  end
@@ -30,7 +30,18 @@ module Concurrent
30
30
 
31
31
  # Raised when an attempt is made to modify an immutable object
32
32
  # (such as an `IVar`) after its final state has been set.
33
- MultipleAssignmentError = Class.new(Error)
33
+ class MultipleAssignmentError < Error
34
+ attr_reader :inspection_data
35
+
36
+ def initialize(message = nil, inspection_data = nil)
37
+ @inspection_data = inspection_data
38
+ super message
39
+ end
40
+
41
+ def inspect
42
+ format '%s %s>', super[0..-2], @inspection_data.inspect
43
+ end
44
+ end
34
45
 
35
46
  # Raised by an `Executor` when it is unable to process a given task,
36
47
  # possibly because of a reject policy or other internal error.
@@ -43,4 +54,16 @@ module Concurrent
43
54
  # Raised when an operation times out.
44
55
  TimeoutError = Class.new(Error)
45
56
 
57
+ # Aggregates multiple exceptions.
58
+ class MultipleErrors < Error
59
+ attr_reader :errors
60
+
61
+ def initialize(errors, message = "#{errors.size} errors")
62
+ @errors = errors
63
+ super [*message,
64
+ *errors.map { |e| [format('%s (%s)', e.message, e.class), *e.backtrace] }.flatten(1)
65
+ ].join("\n")
66
+ end
67
+ end
68
+
46
69
  end
@@ -1,6 +1,5 @@
1
1
  module Concurrent
2
2
  module Synchronization
3
- # TODO (pitr-ch 04-Dec-2016): should be in edge
4
3
  class Condition < LockableObject
5
4
  safe_initialization!
6
5
 
@@ -1,6 +1,5 @@
1
1
  module Concurrent
2
2
  module Synchronization
3
- # TODO (pitr-ch 04-Dec-2016): should be in edge
4
3
  class Lock < LockableObject
5
4
  # TODO use JavaReentrantLock on JRuby
6
5
 
@@ -70,8 +70,8 @@ module Concurrent
70
70
  # any instance variables with CamelCase names and isn't {.safe_initialization?}.
71
71
  def self.ensure_safe_initialization_when_final_fields_are_present
72
72
  Object.class_eval do
73
- def self.new(*)
74
- object = super
73
+ def self.new(*args, &block)
74
+ object = super(*args, &block)
75
75
  ensure
76
76
  has_final_field = object.instance_variables.any? { |v| v.to_s =~ /^@[A-Z]/ }
77
77
  if has_final_field && !safe_initialization?
@@ -30,6 +30,7 @@ module Concurrent
30
30
 
31
31
  def full_memory_barrier
32
32
  # Rubinius instance variables are not volatile so we need to insert barrier
33
+ # TODO (pitr 26-Nov-2015): check comments like ^
33
34
  Rubinius.memory_barrier
34
35
  end
35
36
  end
@@ -1,4 +1,4 @@
1
1
  module Concurrent
2
- VERSION = '1.0.3'
3
- EDGE_VERSION = '0.2.3'
2
+ VERSION = '1.0.4'
3
+ EDGE_VERSION = '0.3.0'
4
4
  end
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: 1.0.3
4
+ version: 1.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jerry D'Antonio
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2016-12-17 00:00:00.000000000 Z
13
+ date: 2016-12-27 00:00:00.000000000 Z
14
14
  dependencies: []
15
15
  description: |
16
16
  Modern concurrency tools including agents, futures, promises, thread pools, actors, supervisors, and more.