Concurrently

Build Status

Concurrently is a concurrency framework for Ruby and mruby. With it, concurrent code can be written sequentially similar to async/await.

The concurrency primitive of Concurrently is the concurrent proc. It is very similar to a regular proc. Calling a concurrent proc creates a concurrent evaluation which is kind of a lightweight thread: It can wait for stuff without blocking other concurrent evaluations.

Under the hood, concurrent procs are evaluated inside fibers. They can wait for readiness of I/O or a period of time (or the result of other concurrent evaluations). The interface is comparable to plain Ruby:

Plain Ruby Concurrently
Fiber.new(&block).resume concurrent_proc(&block).call
IO.select([io]) io.await_readable
IO.select(nil, [io]) io.await_writable
IO.select(nil, nil, nil, seconds) wait(seconds)

Beyond the mere beautification of the interface, Concurrently also takes care of the management of the event loop and the coordination between all concurrent evaluations.

A Basic Example

This is a little server reading from an IO and printing the received messages:

server = concurrent_proc do |io|
  while true
    begin
      puts io.read_nonblock 32
    rescue IO::WaitReadable
      io.await_readable
      retry
    end
  end
end

Now, we create a pipe and start the server with the read end of it:

r,w = IO.pipe
server.call_detached r

Finally, we write messages to the write end of the pipe every 0.5 seconds:

puts "#{Time.now.strftime('%H:%M:%S.%L')} (Start time)"

while true
  wait 0.5
  w.write Time.now.strftime('%H:%M:%S.%L')
end

The evaluation of the root fiber is effectively blocked by waiting or writing messages. But since the server runs concurrently it is not affected by this and happily prints its received messages.

This is the output:

23:20:42.357 (Start time)
23:20:42.858
23:20:43.359
23:20:43.860
23:20:44.360
...

Documentation

Supported Ruby Versions

  • Ruby 2.2.7+
  • mruby 1.3+ (or mruby-head until mruby 1.3 is released)

Development

Release Notes

License

Copyright 2016-present Christopher Aue

Concurrently is licensed under the Apache License, Version 2.0. Please see the file called LICENSE.