module Eldritch::DSL

Provides DSL for:

Public Instance Methods

async(method=nil, &block) click to toggle source

Creates an asynchronous method or starts an async block

If a block is passed, this will be an async block. Otherwise this method will create an async method.

When an async block is called, it will yield the block in a new thread.

async do
  # will run in parallel
end
#=> <Task>

When called, async methods behave exactly like async blocks.

async def foo
  # will run in parallel
end

foo
#=> <Task>

If you are using ruby < 2.1.0, you will need to define async methods like so:

def foo
  # will run in parallel
end
async :foo

@param [Symbol] method the name of the async method. @return [Task] a task representing the async method or block

(only for async block and async method call)
# File lib/eldritch/dsl.rb, line 38
def async(method=nil, &block)
  if block
    async_block(&block)
  else
    async_method(method)
  end
end
sync(task) click to toggle source

Allows async methods to be called like synchronous methods

sync send_email(42) # send_mail is async

@param [Task] task a task returned by {#async} @return whatever the method has returned

# File lib/eldritch/dsl.rb, line 52
def sync(task)
  task.value
end
together() { |group| ... } click to toggle source

Creates a group of async call and blocks

When async blocks and calls are inside a together block, they can act as a group.

A together block waits for all the async call/blocks that were started within itself to stop before continuing.

together do
  5.times do
    async { sleep(1) }
  end
end
# waits for all 5 async blocks to complete

A together block will also yield a {Group}. This can be used to interact with the other async calls/blocks.

together do |group|
  5.times do
    async do
      # stop everyone else
      group.interrupt if something?
    end
  end
end

@yield [Group] group of async blocks/calls @see Group Group class

# File lib/eldritch/dsl.rb, line 82
def together
  old = Thread.current.eldritch_group

  group = Group.new
  Thread.current.eldritch_group = group

  yield group

  group.join_all
  Thread.current.eldritch_group = old
end

Private Instance Methods

async_block(&block) click to toggle source
# File lib/eldritch/dsl.rb, line 96
def async_block(&block)
  task = Task.new do
    begin
      block.call
    rescue InterruptedError
      # exit silently
    end
  end
  Thread.current.eldritch_group << task
  task
end
async_method(method) click to toggle source
# File lib/eldritch/dsl.rb, line 108
def async_method(method)
  new_method = async_method_name(method)
  target = self.kind_of?(Module) ? self : self.class

  target.send :alias_method, new_method, method
  target.send :define_method, method do |*args|
    async { send(new_method, *args) }
  end
end
async_method_name(method) click to toggle source
# File lib/eldritch/dsl.rb, line 118
def async_method_name(method)
  "__async_#{method}".to_sym
end