Concurrent-Ruby

Concurrent Ruby Concurrent-ruby is a gem that was brought my attention during Anil Wadghule’s talk in RubyConf India 2017. Concurrency is the ability of a program to make progress on a task that is spread out over different slices of time. It allows us to run multiple “threads” at the same time. As one thread may be sleeping or waiting on I/O, another thread may take priority and start working, thus making optimal use of available CPU time. When you think of concurrency, think of “threads”. Modern concurrency tools include agents, futures, promises, thread pools actors, supervisors etc.Concurrent Ruby makes the strongest thread safety guarantees of any Ruby concurrency library. Every abstraction in this library is thread safe. Similarly, all are deadlock free and many are fully lock free.

Concurrency Abstractions

  • Async (Concurrent::Async): A mixin module that provides simple asynchronous behavior to a class, turning it into a simple actor.
  • Future (Concurrent::Future): An asynchronous operation that produces a value. It represents a promise to complete an action at some time in the future.
    • Dataflow: Built on Futures, Dataflow allows you to create a task that will be scheduled when all of its data dependencies are available.
  • Promise (Concurrent::Promise): Similar to Futures, with more features. It represents the eventual value returned from the single completion of an operation.
  • ScheduledTask (Concurrent::ScheduledTask): Like a Future scheduled for a specific future time.
  • TimerTask (Concurrent::TimerTask): A Thread that periodically wakes up to perform work at regular intervals.

Installation

gem install concurrent-ruby
or add the following line to Gemfile:
gem 'concurrent-ruby', require: 'concurrent'
and run bundle install from your shell.

Edge Gem Installation

It is a submodule for unstable, highly experimental features that are likely to change often and which may never become part of the core gem. Also for new, experimental version of abstractions already in the core gem. The Edge gem must be installed separately from the core gem:
gem install concurrent-ruby-edge
or add the following line to Gemfile:
gem 'concurrent-ruby-edge', require: 'concurrent-edge'
and run bundle install from your shell.

Usage

Everything within this gem can be loaded simply by requiring it:
require 'concurrent'
To use the tools in the Edge gem it must be required separately:
require 'concurrent-edge'
Eg:
require 'concurrent-edge'
class Hello
  def greet
    sleep 3
    "Hello, #{Time.now}"
  end
end
all_promises = Concurrent::Promises.zip(
  Concurrent::Promises.future { Hello.new.greet },
  Concurrent::Promises.future { Hello.new.greet }
)
all_promises.then { |*values| puts values.inspect }.value
In the above code, it displays greetings. And all these runs concurrently. Here we are using concurrent-edge. It shows the answer as:
Hello, 2016-12-09 08:56:51 +0530
Hello, 2016-12-09 08:56:54 +0530
So generally, the gen concurrent-ruby guarantees thread safety and deadlock free. Also, we can manage CPU time using threads in concurrency.

References

]]>