concurrent-ruby 0.5.0 → 0.6.0.pre.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (90) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +88 -77
  3. data/lib/concurrent.rb +17 -2
  4. data/lib/concurrent/actor.rb +17 -0
  5. data/lib/concurrent/actor_context.rb +31 -0
  6. data/lib/concurrent/actor_ref.rb +39 -0
  7. data/lib/concurrent/agent.rb +12 -3
  8. data/lib/concurrent/async.rb +290 -0
  9. data/lib/concurrent/atomic.rb +5 -9
  10. data/lib/concurrent/cached_thread_pool.rb +39 -137
  11. data/lib/concurrent/channel/blocking_ring_buffer.rb +60 -0
  12. data/lib/concurrent/channel/buffered_channel.rb +83 -0
  13. data/lib/concurrent/channel/channel.rb +11 -0
  14. data/lib/concurrent/channel/probe.rb +19 -0
  15. data/lib/concurrent/channel/ring_buffer.rb +54 -0
  16. data/lib/concurrent/channel/unbuffered_channel.rb +34 -0
  17. data/lib/concurrent/channel/waitable_list.rb +38 -0
  18. data/lib/concurrent/configuration.rb +92 -0
  19. data/lib/concurrent/dataflow.rb +9 -3
  20. data/lib/concurrent/delay.rb +88 -0
  21. data/lib/concurrent/exchanger.rb +31 -0
  22. data/lib/concurrent/fixed_thread_pool.rb +28 -122
  23. data/lib/concurrent/future.rb +10 -5
  24. data/lib/concurrent/immediate_executor.rb +3 -2
  25. data/lib/concurrent/ivar.rb +2 -1
  26. data/lib/concurrent/java_cached_thread_pool.rb +45 -0
  27. data/lib/concurrent/java_fixed_thread_pool.rb +37 -0
  28. data/lib/concurrent/java_thread_pool_executor.rb +194 -0
  29. data/lib/concurrent/per_thread_executor.rb +23 -0
  30. data/lib/concurrent/postable.rb +2 -0
  31. data/lib/concurrent/processor_count.rb +125 -0
  32. data/lib/concurrent/promise.rb +42 -18
  33. data/lib/concurrent/ruby_cached_thread_pool.rb +37 -0
  34. data/lib/concurrent/ruby_fixed_thread_pool.rb +31 -0
  35. data/lib/concurrent/ruby_thread_pool_executor.rb +268 -0
  36. data/lib/concurrent/ruby_thread_pool_worker.rb +69 -0
  37. data/lib/concurrent/simple_actor_ref.rb +124 -0
  38. data/lib/concurrent/thread_local_var.rb +1 -1
  39. data/lib/concurrent/thread_pool_executor.rb +30 -0
  40. data/lib/concurrent/timer_task.rb +13 -10
  41. data/lib/concurrent/tvar.rb +212 -0
  42. data/lib/concurrent/utilities.rb +1 -0
  43. data/lib/concurrent/version.rb +1 -1
  44. data/spec/concurrent/actor_context_spec.rb +37 -0
  45. data/spec/concurrent/actor_ref_shared.rb +313 -0
  46. data/spec/concurrent/actor_spec.rb +9 -1
  47. data/spec/concurrent/agent_spec.rb +97 -96
  48. data/spec/concurrent/async_spec.rb +320 -0
  49. data/spec/concurrent/cached_thread_pool_shared.rb +137 -0
  50. data/spec/concurrent/channel/blocking_ring_buffer_spec.rb +149 -0
  51. data/spec/concurrent/channel/buffered_channel_spec.rb +151 -0
  52. data/spec/concurrent/channel/channel_spec.rb +37 -0
  53. data/spec/concurrent/channel/probe_spec.rb +49 -0
  54. data/spec/concurrent/channel/ring_buffer_spec.rb +126 -0
  55. data/spec/concurrent/channel/unbuffered_channel_spec.rb +132 -0
  56. data/spec/concurrent/configuration_spec.rb +134 -0
  57. data/spec/concurrent/dataflow_spec.rb +109 -27
  58. data/spec/concurrent/delay_spec.rb +77 -0
  59. data/spec/concurrent/exchanger_spec.rb +66 -0
  60. data/spec/concurrent/fixed_thread_pool_shared.rb +136 -0
  61. data/spec/concurrent/future_spec.rb +60 -51
  62. data/spec/concurrent/global_thread_pool_shared.rb +33 -0
  63. data/spec/concurrent/immediate_executor_spec.rb +4 -25
  64. data/spec/concurrent/ivar_spec.rb +36 -23
  65. data/spec/concurrent/java_cached_thread_pool_spec.rb +64 -0
  66. data/spec/concurrent/java_fixed_thread_pool_spec.rb +64 -0
  67. data/spec/concurrent/java_thread_pool_executor_spec.rb +71 -0
  68. data/spec/concurrent/obligation_shared.rb +32 -20
  69. data/spec/concurrent/{global_thread_pool_spec.rb → per_thread_executor_spec.rb} +9 -13
  70. data/spec/concurrent/processor_count_spec.rb +20 -0
  71. data/spec/concurrent/promise_spec.rb +29 -41
  72. data/spec/concurrent/ruby_cached_thread_pool_spec.rb +69 -0
  73. data/spec/concurrent/ruby_fixed_thread_pool_spec.rb +39 -0
  74. data/spec/concurrent/ruby_thread_pool_executor_spec.rb +183 -0
  75. data/spec/concurrent/simple_actor_ref_spec.rb +219 -0
  76. data/spec/concurrent/thread_pool_class_cast_spec.rb +40 -0
  77. data/spec/concurrent/thread_pool_executor_shared.rb +155 -0
  78. data/spec/concurrent/thread_pool_shared.rb +98 -36
  79. data/spec/concurrent/tvar_spec.rb +137 -0
  80. data/spec/spec_helper.rb +4 -0
  81. data/spec/support/functions.rb +4 -0
  82. metadata +85 -20
  83. data/lib/concurrent/cached_thread_pool/worker.rb +0 -91
  84. data/lib/concurrent/channel.rb +0 -63
  85. data/lib/concurrent/fixed_thread_pool/worker.rb +0 -54
  86. data/lib/concurrent/global_thread_pool.rb +0 -42
  87. data/spec/concurrent/cached_thread_pool_spec.rb +0 -101
  88. data/spec/concurrent/channel_spec.rb +0 -86
  89. data/spec/concurrent/fixed_thread_pool_spec.rb +0 -92
  90. data/spec/concurrent/uses_global_thread_pool_shared.rb +0 -64
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: fbc70b72314ff5cf4607764c2e542b5a82d40749
4
- data.tar.gz: 37bd7b03c39b679d06155efc494509d9cf458b8c
3
+ metadata.gz: 8e4a4e756232abaffd4ca55c37e049af25f9884a
4
+ data.tar.gz: 9345ebbf4f1a05e1c5b0eccd8df0d111407c293e
5
5
  SHA512:
6
- metadata.gz: 98bc47e45b277667f4040757848fffc83c5836885f445b9eb242658bca1af78271a72be563e7f38c504af1e9c23db44af5abc7f25c2f12b527f8ac3d35271c94
7
- data.tar.gz: f9328fde5f48922e1497683c7593fade6fc5aa79b9fe6e3de322a92530f61f872a77dd54165176adb307a2bfabcce66a4c975d4c6b2507fbc636b0fa18664fb7
6
+ metadata.gz: 1e5b34f7f631e3cb76248674f8cae5b1bee56c8485c71f32cff53d2625fb5475d84e7ff0b1f07272efbfe860652f391ea5f1078652e0c47edc2117a5099152e1
7
+ data.tar.gz: 5c736c6a669fd952268275f9b1e802f32eac4dc78386df90b871f1bb6dc66985b9b5e7e2046ce5bf81235608c1bc3340a1dcbd49573fb65d8cacf8b6b53f3d06
data/README.md CHANGED
@@ -1,26 +1,37 @@
1
1
  # Concurrent Ruby
2
2
  [![Gem Version](https://badge.fury.io/rb/concurrent-ruby.png)](http://badge.fury.io/rb/concurrent-ruby) [![Build Status](https://secure.travis-ci.org/jdantonio/concurrent-ruby.png)](https://travis-ci.org/jdantonio/concurrent-ruby?branch=master) [![Coverage Status](https://coveralls.io/repos/jdantonio/concurrent-ruby/badge.png)](https://coveralls.io/r/jdantonio/concurrent-ruby) [![Code Climate](https://codeclimate.com/github/jdantonio/concurrent-ruby.png)](https://codeclimate.com/github/jdantonio/concurrent-ruby) [![Inline docs](http://inch-pages.github.io/github/jdantonio/concurrent-ruby.png)](http://inch-pages.github.io/github/jdantonio/concurrent-ruby) [![Dependency Status](https://gemnasium.com/jdantonio/concurrent-ruby.png)](https://gemnasium.com/jdantonio/concurrent-ruby)
3
3
 
4
- ***NOTE:*** *A few API updates in v0.5.0 are not backward-compatible. Please see the [release notes](https://github.com/jdantonio/concurrent-ruby/wiki/API-Updates-in-v0.5.0).*
5
-
4
+ <table>
5
+ <tr>
6
+ <td align="left" valign="top">
7
+ <p>
6
8
  Modern concurrency tools for Ruby. Inspired by
7
- [Erlang](http://www.erlang.org/doc/reference_manual/processes.html),
8
- [Clojure](http://clojure.org/concurrent_programming),
9
- [Scala](http://www.scala-lang.org/api/current/index.html#scala.actors.Actor),
10
- [Haskell](http://www.haskell.org/haskellwiki/Applications_and_libraries/Concurrency_and_parallelism#Concurrent_Haskell),
11
- [F#](http://blogs.msdn.com/b/dsyme/archive/2010/02/15/async-and-parallel-design-patterns-in-f-part-3-agents.aspx),
12
- [C#](http://msdn.microsoft.com/en-us/library/vstudio/hh191443.aspx),
13
- [Java](http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/package-summary.html),
9
+ <a href="http://www.erlang.org/doc/reference_manual/processes.html">Erlang</a>,
10
+ <a href="http://clojure.org/concurrent_programming">Clojure</a>,
11
+ <a href="http://www.scala-lang.org/api/current/index.html#scala.actors.Actor">Scala</a>,
12
+ <a href="http://www.haskell.org/haskellwiki/Applications_and_libraries/Concurrency_and_parallelism#Concurrent_Haskell">Haskell</a>,
13
+ <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>,
14
+ <a href="http://msdn.microsoft.com/en-us/library/vstudio/hh191443.aspx">C#</a>,
15
+ <a href="http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/package-summary.html">Java</a>,
14
16
  and classic concurrency patterns.
15
-
17
+ </p>
18
+ <p>
16
19
  The design goals of this gem are:
17
-
18
- * Stay true to the spirit of the languages providing inspiration
19
- * But implement in a way that makes sense for Ruby
20
- * Keep the semantics as idiomatic Ruby as possible
21
- * Support features that make sense in Ruby
22
- * Exclude features that don't make sense in Ruby
23
- * Be small, lean, and loosely coupled
20
+ <ul>
21
+ <li>Stay true to the spirit of the languages providing inspiration</li>
22
+ <li>But implement in a way that makes sense for Ruby</li>
23
+ <li>Keep the semantics as idiomatic Ruby as possible</li>
24
+ <li>Support features that make sense in Ruby</li>
25
+ <li>Exclude features that don't make sense in Ruby</li>
26
+ <li>Be small, lean, and loosely coupled</li>
27
+ </ul>
28
+ </p>
29
+ </td>
30
+ <td align="right" valign="top">
31
+ <img src="https://raw.githubusercontent.com/wiki/jdantonio/concurrent-ruby/logo/concurrent-ruby-logo-300x300.png"/>
32
+ </td>
33
+ </tr>
34
+ </table>
24
35
 
25
36
  ## Features & Documentation
26
37
 
@@ -29,19 +40,21 @@ or the [API documentation](http://rubydoc.info/github/jdantonio/concurrent-ruby/
29
40
  for more information or join our [mailing list](http://groups.google.com/group/concurrent-ruby).
30
41
 
31
42
  There are many concurrency abstractions in this library. These abstractions can be broadly categorized
32
- into several general categories:
33
-
34
- * Asynchronous concurrency abstractions including [Actor](https://github.com/jdantonio/concurrent-ruby/wiki/Actor),
35
- [Agent](https://github.com/jdantonio/concurrent-ruby/wiki/Agent), [Channel](https://github.com/jdantonio/concurrent-ruby/wiki/Channel),
36
- [Future](https://github.com/jdantonio/concurrent-ruby/wiki/Future), [Promise](https://github.com/jdantonio/concurrent-ruby/wiki/Promise),
37
- [ScheculedTask](https://github.com/jdantonio/concurrent-ruby/wiki/ScheduledTask),
43
+ into several general groups:
44
+
45
+ * Asynchronous concurrency abstractions including
46
+ [Async](https://github.com/jdantonio/concurrent-ruby/wiki/Async),
47
+ [Agent](https://github.com/jdantonio/concurrent-ruby/wiki/Agent),
48
+ [Future](https://github.com/jdantonio/concurrent-ruby/wiki/Future),
49
+ [Promise](https://github.com/jdantonio/concurrent-ruby/wiki/Promise),
50
+ [ScheduledTask](https://github.com/jdantonio/concurrent-ruby/wiki/ScheduledTask),
38
51
  and [TimerTask](https://github.com/jdantonio/concurrent-ruby/wiki/TimerTask)
39
52
  * Erlang-inspired [Supervisor](https://github.com/jdantonio/concurrent-ruby/wiki/Supervisor) and other lifecycle classes/mixins
40
53
  for managing long-running threads
41
54
  * Thread-safe variables including [M-Structures](https://github.com/jdantonio/concurrent-ruby/wiki/MVar-(M-Structure)),
42
55
  [I-Structures](https://github.com/jdantonio/concurrent-ruby/wiki/IVar-(I-Structure)),
43
56
  [thread-local variables](https://github.com/jdantonio/concurrent-ruby/wiki/ThreadLocalVar),
44
- and atomic counters
57
+ atomic counters, and [software transactional memory](https://github.com/jdantonio/concurrent-ruby/wiki/TVar-(STM))
45
58
  * Thread synchronization classes and algorithms including [dataflow](https://github.com/jdantonio/concurrent-ruby/wiki/Dataflow),
46
59
  timeout, condition, countdown latch, dependency counter, and event
47
60
  * Java-inspired [thread pools](https://github.com/jdantonio/concurrent-ruby/wiki/Thread%20Pools)
@@ -53,73 +66,68 @@ This gem adheres to the rules of [semantic versioning](http://semver.org/).
53
66
 
54
67
  ### Supported Ruby versions
55
68
 
56
- MRI 1.9.2, 1.9.3, 2.0, 2.1, JRuby (1.9 mode), and Rubinius 2.x. This library is pure Ruby and has no gem dependencies.
57
- It should be fully compatible with any Ruby interpreter that is 1.9.x compliant.
69
+ MRI 1.9.3, 2.0, 2.1, JRuby (1.9 mode), and Rubinius 2.x.
70
+ This library is pure Ruby and has no gem dependencies.
71
+ It should be fully compatible with any interpreter that is compliant with Ruby 1.9.3 or newer.
58
72
 
59
- ### Example
73
+ ### Examples
60
74
 
61
75
  Many more code examples can be found in the documentation for each class (linked above).
62
76
  This one simple example shows some of the power of this gem.
63
77
 
64
78
  ```ruby
65
79
  require 'concurrent'
66
- require 'faker'
67
-
68
- class EchoActor < Concurrent::Actor
69
- def act(*message)
70
- puts "#{message} handled by #{self}"
80
+ require 'thread' # for Queue
81
+ require 'open-uri' # for open(uri)
82
+
83
+ class Ticker
84
+ def get_year_end_closing(symbol, year)
85
+ uri = "http://ichart.finance.yahoo.com/table.csv?s=#{symbol}&a=11&b=01&c=#{year}&d=11&e=31&f=#{year}&g=m"
86
+ data = open(uri) {|f| f.collect{|line| line.strip } }
87
+ data[1].split(',')[4].to_f
71
88
  end
72
89
  end
73
90
 
74
- mailbox, pool = EchoActor.pool(5)
75
-
76
- timer_proc = proc do
77
- mailbox.post(Faker::Company.bs)
78
- end
79
-
80
- t1 = Concurrent::TimerTask.new(execution_interval: rand(5)+1, &timer_proc)
81
- t2 = Concurrent::TimerTask.new(execution_interval: rand(5)+1, &timer_proc)
82
-
83
- overlord = Concurrent::Supervisor.new
84
-
85
- overlord.add_worker(t1)
86
- overlord.add_worker(t2)
87
- pool.each{|actor| overlord.add_worker(actor)}
88
-
89
- overlord.run!
90
-
91
- #=> ["mesh proactive platforms"] handled by #<EchoActor:0x007fa5ac18bdf8>
92
- #=> ["maximize sticky portals"] handled by #<EchoActor:0x007fa5ac18bdd0>
93
- #=> ["morph bleeding-edge markets"] handled by #<EchoActor:0x007fa5ac18bd80>
94
- #=> ["engage clicks-and-mortar interfaces"] handled by #<EchoActor:0x007fa5ac18bd58>
95
- #=> ["monetize transparent infrastructures"] handled by #<EchoActor:0x007fa5ac18bd30>
96
- #=> ["morph sexy e-tailers"] handled by #<EchoActor:0x007fa5ac18bdf8>
97
- #=> ["exploit dot-com models"] handled by #<EchoActor:0x007fa5ac18bdd0>
98
- #=> ["incentivize virtual deliverables"] handled by #<EchoActor:0x007fa5ac18bd80>
99
- #=> ["enhance B2B models"] handled by #<EchoActor:0x007fa5ac18bd58>
100
- #=> ["envisioneer real-time architectures"] handled by #<EchoActor:0x007fa5ac18bd30>
101
-
102
- overlord.stop
91
+ # Future
92
+ price = Concurrent::Future.execute{ Ticker.new.get_year_end_closing('TWTR', 2013) }
93
+ price.state #=> :pending
94
+ sleep(1) # do other stuff
95
+ price.value #=> 63.65
96
+ price.state #=> :fulfilled
97
+
98
+ # Promise
99
+ prices = Concurrent::Promise.new{ puts Ticker.new.get_year_end_closing('AAPL', 2013) }.
100
+ then{ puts Ticker.new.get_year_end_closing('MSFT', 2013) }.
101
+ then{ puts Ticker.new.get_year_end_closing('GOOG', 2013) }.
102
+ then{ puts Ticker.new.get_year_end_closing('AMZN', 2013) }.execute
103
+ prices.state #=> :pending
104
+ sleep(1) # do other stuff
105
+ #=> 561.02
106
+ #=> 37.41
107
+ #=> 1120.71
108
+ #=> 398.79
109
+
110
+ # ScheduledTask
111
+ task = Concurrent::ScheduledTask.execute(2){ Ticker.new.get_year_end_closing('INTC', 2013) }
112
+ task.state #=> :pending
113
+ sleep(3) # do other stuff
114
+ task.value #=> 25.96
115
+
116
+ # Async
117
+ ticker = Ticker.new
118
+ ticker.extend(Concurrent::Async)
119
+ hpq = ticker.async.get_year_end_closing('HPQ', 2013)
120
+ ibm = ticker.await.get_year_end_closing('IBM', 2013)
121
+ hpq.value #=> 27.98
122
+ ibm.value #=> 187.57
103
123
  ```
104
124
 
105
- ### Disclaimer
106
-
107
- Remember, *there is no silver bullet in concurrent programming.* Concurrency is hard.
108
- These tools will help ease the burden, but at the end of the day it is essential that you
109
- *know what you are doing.*
110
-
111
- * Decouple business logic from concurrency logic
112
- * Test business logic separate from concurrency logic
113
- * Keep the intersection of business logic and concurrency and small as possible
114
- * Don't share mutable data unless absolutely necessary
115
- * Protect shared data as much as possible (prefer [immutability](https://github.com/harukizaemon/hamster))
116
- * Don't mix Ruby's [concurrency](http://ruby-doc.org/core-2.0.0/Thread.html)
117
- [primitives](http://www.ruby-doc.org/core-2.0.0/Mutex.html) with asynchronous concurrency libraries
118
-
119
125
  ## Contributors
120
126
 
127
+ * [Jerry D'Antonio](https://github.com/jdantonio)
121
128
  * [Michele Della Torre](https://github.com/mighe)
122
129
  * [Chris Seaton](https://github.com/chrisseaton)
130
+ * [Lucas Allan](https://github.com/lucasallan)
123
131
  * [Giuseppe Capizzi](https://github.com/gcapizzi)
124
132
  * [Brian Shirai](https://github.com/brixen)
125
133
  * [Chip Miller](https://github.com/chip-miller)
@@ -136,5 +144,8 @@ These tools will help ease the burden, but at the end of the day it is essential
136
144
 
137
145
  ## License and Copyright
138
146
 
139
- *Concurrent Ruby* is Copyright &copy; 2013 [Jerry D'Antonio](https://twitter.com/jerrydantonio).
140
- It is free software released under the [MIT License](http://www.opensource.org/licenses/MIT).
147
+ *Concurrent Ruby* is free software released under the [MIT License](http://www.opensource.org/licenses/MIT).
148
+
149
+ The *Concurrent Ruby* [logo](https://github.com/jdantonio/concurrent-ruby/wiki/Logo)
150
+ was designed by [David Jones](https://twitter.com/zombyboy).
151
+ It is Copyright &copy; 2014 [Jerry D'Antonio](https://twitter.com/jerrydantonio). All Rights Reserved.
@@ -1,4 +1,5 @@
1
1
  require 'concurrent/version'
2
+ require 'concurrent/configuration'
2
3
 
3
4
  require 'concurrent/atomic'
4
5
  require 'concurrent/count_down_latch'
@@ -10,14 +11,17 @@ require 'concurrent/ivar'
10
11
 
11
12
  require 'concurrent/actor'
12
13
  require 'concurrent/agent'
13
- require 'concurrent/channel'
14
+ require 'concurrent/async'
14
15
  require 'concurrent/dataflow'
16
+ require 'concurrent/delay'
15
17
  require 'concurrent/dereferenceable'
16
18
  require 'concurrent/event'
19
+ require 'concurrent/exchanger'
17
20
  require 'concurrent/future'
18
21
  require 'concurrent/mvar'
19
22
  require 'concurrent/obligation'
20
23
  require 'concurrent/postable'
24
+ require 'concurrent/processor_count'
21
25
  require 'concurrent/promise'
22
26
  require 'concurrent/runnable'
23
27
  require 'concurrent/scheduled_task'
@@ -25,13 +29,24 @@ require 'concurrent/stoppable'
25
29
  require 'concurrent/supervisor'
26
30
  require 'concurrent/thread_local_var'
27
31
  require 'concurrent/timer_task'
32
+ require 'concurrent/tvar'
28
33
  require 'concurrent/utilities'
29
34
 
30
- require 'concurrent/global_thread_pool'
35
+ require 'concurrent/channel/probe'
36
+ require 'concurrent/channel/channel'
37
+ require 'concurrent/channel/unbuffered_channel'
38
+ require 'concurrent/channel/buffered_channel'
39
+ require 'concurrent/channel/ring_buffer'
40
+ require 'concurrent/channel/blocking_ring_buffer'
41
+
42
+ require 'concurrent/actor_context'
43
+ require 'concurrent/simple_actor_ref'
31
44
 
32
45
  require 'concurrent/cached_thread_pool'
33
46
  require 'concurrent/fixed_thread_pool'
34
47
  require 'concurrent/immediate_executor'
48
+ require 'concurrent/per_thread_executor'
49
+ require 'concurrent/thread_pool_executor'
35
50
 
36
51
  # Modern concurrency tools for Ruby. Inspired by Erlang, Clojure, Scala, Haskell,
37
52
  # F#, C#, Java, and classic concurrency patterns.
@@ -119,6 +119,8 @@ module Concurrent
119
119
  #
120
120
  # ping << :pong
121
121
  #
122
+ # @deprecated +Actor+ is being replaced with a completely new framework prior to v1.0.0
123
+ #
122
124
  # @see http://ruby-doc.org/stdlib-2.0/libdoc/observer/rdoc/Observable.html
123
125
  class Actor
124
126
  include Observable
@@ -174,7 +176,10 @@ module Concurrent
174
176
  # #=> [6] handled by #<EchoActor:0x007fc8014fb8b8>
175
177
  # #=> [7] handled by #<EchoActor:0x007fc8014fb818>
176
178
  # #=> [8] handled by #<EchoActor:0x007fc8014fb890>
179
+ #
180
+ # @deprecated +Actor+ is being replaced with a completely new framework prior to v1.0.0
177
181
  def self.pool(count, *args, &block)
182
+ warn '[DEPRECATED] `Actor` is deprecated and will be replaced with `ActorContext`.'
178
183
  raise ArgumentError.new('count must be greater than zero') unless count > 0
179
184
  mailbox = Queue.new
180
185
  actors = count.times.collect do
@@ -202,24 +207,34 @@ module Concurrent
202
207
  # @return [Object] the result obtained when the message is successfully processed
203
208
  #
204
209
  # @raise NotImplementedError unless overridden in the +Actor+ subclass
210
+ #
211
+ # @deprecated +Actor+ is being replaced with a completely new framework prior to v1.0.0
205
212
  #
206
213
  # @!visibility public
207
214
  def act(*message)
215
+ warn '[DEPRECATED] `Actor` is deprecated and will be replaced with `ActorContext`.'
208
216
  raise NotImplementedError.new("#{self.class} does not implement #act")
209
217
  end
210
218
 
211
219
  # @!visibility private
220
+ #
221
+ # @deprecated +Actor+ is being replaced with a completely new framework prior to v1.0.0
212
222
  def on_run # :nodoc:
223
+ warn '[DEPRECATED] `Actor` is deprecated and will be replaced with `ActorContext`.'
213
224
  queue.clear
214
225
  end
215
226
 
216
227
  # @!visibility private
228
+ #
229
+ # @deprecated +Actor+ is being replaced with a completely new framework prior to v1.0.0
217
230
  def on_stop # :nodoc:
218
231
  queue.clear
219
232
  queue.push(:stop)
220
233
  end
221
234
 
222
235
  # @!visibility private
236
+ #
237
+ # @deprecated +Actor+ is being replaced with a completely new framework prior to v1.0.0
223
238
  def on_task # :nodoc:
224
239
  package = queue.pop
225
240
  return if package == :stop
@@ -247,6 +262,8 @@ module Concurrent
247
262
  end
248
263
 
249
264
  # @!visibility private
265
+ #
266
+ # @deprecated +Actor+ is being replaced with a completely new framework prior to v1.0.0
250
267
  def on_error(time, msg, ex) # :nodoc:
251
268
  end
252
269
  end
@@ -0,0 +1,31 @@
1
+ require 'concurrent/simple_actor_ref'
2
+
3
+ module Concurrent
4
+
5
+ module ActorContext
6
+
7
+ def on_start
8
+ end
9
+
10
+ def on_reset
11
+ end
12
+
13
+ def on_shutdown
14
+ end
15
+
16
+ def on_error(time, message, exception)
17
+ end
18
+
19
+ def self.included(base)
20
+
21
+ class << base
22
+ protected :new
23
+
24
+ def spawn(opts = {})
25
+ args = opts.fetch(:args, [])
26
+ Concurrent::SimpleActorRef.new(self.new(*args), opts)
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,39 @@
1
+ require 'concurrent/copy_on_notify_observer_set'
2
+
3
+ module Concurrent
4
+
5
+ module ActorRef
6
+
7
+ #NOTE: Required API methods
8
+ # Must be implemented in all subclasses
9
+ #def post(*msg, &block)
10
+ #def post!(*msg)
11
+ #def running?
12
+ #def shutdown?
13
+ #def shutdown
14
+ #def join(timeout = nil)
15
+
16
+ def <<(message)
17
+ post(*message)
18
+ self
19
+ end
20
+
21
+ def add_observer(*args)
22
+ @observers.add_observer(*args)
23
+ end
24
+
25
+ def delete_observer(*args)
26
+ @observers.delete_observer(*args)
27
+ end
28
+
29
+ def delete_observers
30
+ @observers.delete_observers
31
+ end
32
+
33
+ protected
34
+
35
+ def observers
36
+ @observers ||= CopyOnNotifyObserverSet.new
37
+ end
38
+ end
39
+ end
@@ -1,8 +1,8 @@
1
1
  require 'thread'
2
2
  require 'observer'
3
3
 
4
+ require 'concurrent/configuration'
4
5
  require 'concurrent/dereferenceable'
5
- require 'concurrent/global_thread_pool'
6
6
  require 'concurrent/utilities'
7
7
 
8
8
  module Concurrent
@@ -34,7 +34,7 @@ module Concurrent
34
34
  # @return [Fixnum] the maximum number of seconds before an update is cancelled
35
35
  class Agent
36
36
  include Dereferenceable
37
- include UsesGlobalThreadPool
37
+ include OptionsParser
38
38
 
39
39
  # The default timeout value (in seconds); used when no timeout option
40
40
  # is given at initialization
@@ -46,7 +46,15 @@ module Concurrent
46
46
  #
47
47
  # @param [Object] initial the initial value
48
48
  # @param [Hash] opts the options used to define the behavior at update and deref
49
+ #
49
50
  # @option opts [Fixnum] :timeout (TIMEOUT) maximum number of seconds before an update is cancelled
51
+ #
52
+ # @option opts [Boolean] :operation (false) when +true+ will execute the future on the global
53
+ # operation pool (for long-running operations), when +false+ will execute the future on the
54
+ # global task pool (for short-running tasks)
55
+ # @option opts [object] :executor when provided will run all operations on
56
+ # this executor rather than the global thread pool (overrides :operation)
57
+ #
50
58
  # @option opts [String] :dup_on_deref (false) call +#dup+ before returning the data
51
59
  # @option opts [String] :freeze_on_deref (false) call +#freeze+ before returning the data
52
60
  # @option opts [String] :copy_on_deref (nil) call the given +Proc+ passing the internal value and
@@ -57,6 +65,7 @@ module Concurrent
57
65
  @validator = Proc.new { |result| true }
58
66
  @timeout = opts.fetch(:timeout, TIMEOUT).freeze
59
67
  @observers = CopyOnWriteObserverSet.new
68
+ @executor = get_executor_from(opts)
60
69
  init_mutex
61
70
  set_deref_options(opts)
62
71
  end
@@ -116,7 +125,7 @@ module Concurrent
116
125
  # @yieldparam [Object] value the current value
117
126
  # @yieldreturn [Object] the new value
118
127
  def post(&block)
119
- Agent.thread_pool.post{ work(&block) } unless block.nil?
128
+ @executor.post{ work(&block) } unless block.nil?
120
129
  end
121
130
 
122
131
  # Update the current value with the result of the given block operation