The dark arts of concurrent programming.
A DSL that adds parallel programming constructs to make your life a little easier.
- Install it
gem install eldritch - Require it
require 'eldritch' - Use it (see features below)
By default eldritch will inject the DSL into the global scope. If you don't want this, you can require eldritch/safe
instead of eldritch.
require'eldricth/safe'classMyClassincludeEldritch::DSLextendEldritch::DSL# The DSL is available in this classendAsync methods run concurrently when called. The caller is returned control right away and the method runs in the background.
require'eldritch'# define an async methodasyncdefsend_email(email)# ...endsend_email(some_email)# runs in the backgroundFor all versions of ruby before 2.1.0, you need to define async methods like so:
deffoo# stuffendasync:fooSince ruby 2.1.0, def returns the name of the method defined as a symbol. This allows for the cleaner async def foo
syntax.
Async blocks are run concurrently.
require'eldritch'asyncdo# runs in the backgroundendAsync blocks and async methods both return tasks. These can be used to interact with the async block/method.
require'eldritch'task=asyncdo# calculate something that will take a long timeend# we need to result of the taskres=2 + task.value# waits for the task to finishTogether blocks are used to control all async blocks and methods within them as a group. Before exiting, together blocks wait for all their async calls to be done before returning.
require'eldritch'togetherdo1000.timesdoasyncdo# do some workendendend# all 1000 tasks are doneThese blocks can also take an argument. This argument is a group that can be used to control the async calls in the block. See the documentation for Eldritch::Group for more information.
require'eldritch'togetherdo |group|
5.timesdoasyncdo# do somethinggroup.interruptifsome_condition# stops all other tasksendendendMRI has this nasty little feature called a GIL or Global Interpreter Lock. This lock makes it so that only one thread can run at a time. Let's say that you have 4 cores, running threaded code on MRI will only make use of 1 core. Sometimes, you might not gain a speed boost if you make code parallel. This could the case even if theory says otherwise.
Not all ruby implementations use a GIL. For example, jRuby does not use a GIL.
If your ruby implementation has a GIL, you will probably see a speed boost if your code does a lot of IO or anything that's blocking. In that case running on a single core is not that much of a hindrance, because most of the threads will be blocked and your code should run more often.
If you installed eldritch with gem, you can just run the examples directly. If you are running them against a clone of
this repository you need to add lib/ to the include path.
$ ruby -Ilib examples/the_example.rb
Be aware that if you are running ruby < 2.1.0, some the examples may not work. All the examples that define async
methods with async def something; end will not work. This is because, since ruby 2.1.0, def returns the name of the
method defined as a symbol.

