Class: Muscle

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/muscle.rb

Instance Method Summary collapse

Constructor Details

#initialize {|_self| ... } ⇒ Muscle

Returns a new instance of Muscle.

Yields:

  • (_self)

Yield Parameters:

  • _self (Muscle)

    the object that the method was called on



5
6
7
8
# File 'lib/muscle.rb', line 5

def initialize
  @threads, @values, @names, @timeouts = {}, {}, [], {}
  yield self
end

Instance Method Details

#[](name) ⇒ Object

Access the results of the slow action if the action is not yet completed, the process will block until it’s done.

:api: public



70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/muscle.rb', line 70

def [](name)
  return @values[name] unless @values[name].nil?
  begin
    if @threads[name]
      @values[name] = @threads[name].join.value
      @threads.delete(name)
    end
    @values[name]
  rescue Timeout::Error => e
    if to = (@timeouts[name] || @timeouts[:any])
      to.call(name)
    else
      raise e
    end
  end
end

#action(name = random_name, opts = {}, &block) ⇒ Object

Use this to declare actions for the muscle to perform

Example:

m = Muscle.new do |m|

m.action(:github) do
  Net::HTTP.start("github.com"){|h| h.get("/")}
end
m.action(:failblog) do
  Net::HTTP.start("failblog.com"){|h| h.get("/")}
end

end

This will setup a muscle to fetch the page from github.com/ and failblog.com/ and make them available in the muscle. The pages are fetched in the background and will not block until you access the results of the action

options -

+timeout+ A default timeout of 5 seconds is included.  Set this option for custom timeouts

:api: pulbic



31
32
33
34
35
36
# File 'lib/muscle.rb', line 31

def action(name = random_name, opts = {}, &block)
  opts[:timeout] ||= 5
  @names << name
  @threads[name] = Thread.new{Timeout::timeout(opts[:timeout], &block)}
  name
end

#eachObject

Iterate through the results of each action in declared order. Will block on any uncompleted action

:api: public



91
92
93
# File 'lib/muscle.rb', line 91

def each
  @names.each{|n| yield self[n]}
end

#on_timeout(*names, &block) ⇒ Object

Use this to set a timeout on a given action, or on all actions

Example

m.on_timeout(:foo){|name| "#{name} timed out"}
m.on_timeout(:bar){|name| "#{name} timed out"}

This example sets a return value for timed out actions and replaces the exception with the results of the block. If no timeout is set, the original timeout exception is returned.

You can also mass declare on_timeout hooks to respond in the same way. The above example would compress to

m.on_timeout(:foo, :bar){|name| "#{name} timed out"}

You can also setup a catch all timeout response as a fall back like this

m.on_timeout{|name| "#{name} timed out"}

You can mix and match as many on_timeout handlers as you need. Named handlers will take precedence over the non-named handlers

:api: public



59
60
61
62
63
64
# File 'lib/muscle.rb', line 59

def on_timeout(*names, &block)
  names = [:any] if names.empty?
  names.each do |n|
    @timeouts[n] = block
  end
end