Modern concurrency tools for Ruby. Inspired by Erlang, Clojure, Scala, Haskell, F#, C#, Java, and classic concurrency patterns. The design goals of this gem are:
|
gem install concurrent-ruby
or add the following line to Gemfile:
gem 'concurrent-ruby'
and run bundle install
from your shell.
NOTE: There is an old gem from 2007 called "concurrent" that does not appear to be under active development. That isn't us. Please do not run* gem install concurrent
*. It is not the droid you are looking for.
Please see the Concurrent Ruby Wiki or the API documentation for more information or join our mailing list.
There are many concurrency abstractions in this library. These abstractions can be broadly categorized into several general groups:
- Asynchronous concurrency abstractions including Agent, Async, Future, Promise, ScheduledTask, and TimerTask
- Fast, light-weight Actor model implementation.
- Thread-safe variables including I-Structures, M-Structures, thread-local variables, and software transactional memory
- Thread synchronization classes and algorithms including condition, countdown latch, dataflow, event, exchanger, and timeout
- Java-inspired executors (thread pools and more)
- And many more...
This gem adheres to the rules of semantic versioning.
MRI 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. It should be fully compatible with any interpreter that is compliant with Ruby 1.9.3 or newer.
Many more code examples can be found in the documentation for each class (linked above).
Future and ScheduledTask:
require 'concurrent'
require 'thread' # for Queue
require 'open-uri' # for open(uri)
class Ticker
def get_year_end_closing(symbol, year)
uri = "http://ichart.finance.yahoo.com/table.csv?s=#{symbol}&a=11&b=01&c=#{year}&d=11&e=31&f=#{year}&g=m"
data = open(uri) {|f| f.collect{|line| line.strip } }
data[1].split(',')[4].to_f
end
end
# Future
price = Concurrent::Future.execute{ Ticker.new.get_year_end_closing('TWTR', 2013) }
price.state #=> :pending
sleep(1) # do other stuff
price.value #=> 63.65
price.state #=> :fulfilled
# ScheduledTask
task = Concurrent::ScheduledTask.execute(2){ Ticker.new.get_year_end_closing('INTC', 2013) }
task.state #=> :pending
sleep(3) # do other stuff
task.value #=> 25.96
Actor:
class Counter < Concurrent::Actor::Context
# Include context of an actor which gives this class access to reference
# and other information about the actor
# use initialize as you wish
def initialize(initial_value)
@count = initial_value
end
# override on_message to define actor's behaviour
def on_message(message)
if Integer === message
@count += message
end
end
end #
# Create new actor naming the instance 'first'.
# Return value is a reference to the actor, the actual actor is never returned.
counter = Counter.spawn(:first, 5)
# Tell a message and forget returning self.
counter.tell(1)
counter << 1
# (First counter now contains 7.)
# Send a messages asking for a result.
counter.ask(0).class
counter.ask(0).value
- Fork it
- Create your feature branch (
git checkout -b my-new-feature
) - Commit your changes (
git commit -am 'Add some feature'
) - Push to the branch (
git push origin my-new-feature
) - Create new Pull Request
Concurrent Ruby is free software released under the MIT License.
The Concurrent Ruby logo was designed by David Jones. It is Copyright © 2014 Jerry D'Antonio. All Rights Reserved.