Concurrently
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
License
Copyright 2016-present Christopher Aue
Concurrently is licensed under the Apache License, Version 2.0. Please see the file called LICENSE.