Module: Obligation

Included in:
Base
Defined in:
lib/obligation.rb,
lib/obligation/impl.rb,
lib/obligation/version.rb

Overview

# Obligation

An Obligation represent a future result. It allows to do other things while something is calculated in the background and wait for it’s value when needed.

This implementation also supports various kinds of callbacks and data flow specification to integration into thread, fibered as well as evented environments.

Defined Under Namespace

Modules: Impl, VERSION Classes: Base, Dependent, RejectedError, StateError, TimeoutError, Value

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.create(*args, &block) ⇒ Object



177
178
179
# File 'lib/obligation.rb', line 177

def create(*args, &block)
  Impl.create(*args, &block)
end

.on(*obligations) ⇒ Object



181
182
183
# File 'lib/obligation.rb', line 181

def on(*obligations)
  Impl.on(*obligations)
end

Instance Method Details

#fulfilled?Boolean

Check if Obligation is fulfilled.

Examples:

o = Obligation.create do |w|
  Thread.new { sleep 1; w.fulfill 42 }
end

o.fulfilled? #=> false
o.value
o.fulfilled? #=> true

Returns:

  • (Boolean)

    True if Obligation is fulfilled, false otherwise.



119
120
121
# File 'lib/obligation.rb', line 119

def fulfilled?
  throw NotImplementedError.new 'Obligation#fulfilled? not implemented.'
end

#pending?Boolean

Check if Obligation is pending e.g. neither fulfilled or rejected.

Examples:

o = Obligation.create do |w|
  Thread.new { sleep 1; w.fulfill 42 }
end

o.pending? #=> true
o.value
o.pending? #=> false

Returns:

  • (Boolean)

    True if Obligation is pending, false otherwise.



136
137
138
# File 'lib/obligation.rb', line 136

def pending?
  throw NotImplementedError.new 'Obligation#pending? not implemented.'
end

#rejected?Boolean

Check if Obligation is rejected.

Examples:

o = Obligation.create do |w|
  Thread.new { sleep 1; w.reject StandardError.new }
end

o.rejected? #=> false
o.value
o.pending? #=> true

Returns:

  • (Boolean)

    True if Obligation is rejected, false otherwise.



153
154
155
# File 'lib/obligation.rb', line 153

def rejected?
  throw NotImplementedError.new 'Obligation#rejected? not implemented.'
end

#then {|result| ... } ⇒ Obligation

Execute given block with Obligation result.

The moment of execution is not specified and MAY not be directly after Obligation was fulfilled. Execution of the callback SHALL be on same thread as the current.

If callback returns an Obligation the outer returned Obligation MUST wait on the returned one from the callback. This allows seamless integration with any library using Obligations to handle delayed return values (see example 3).

Examples:

Simple data flow

o1 = Obligation.create do |w|
  Thread.new do
    sleep 1 # Heavy calculation
    w.fulfill 42
  end
end

o2 = o1.then do |result|
  result - 5 + 1300
end

o2.value #=> 1337

Callback with another Obligation

o1 = Obligation.create do |w|
  Thread.new do
    sleep 1 # Heavy calculation
    w.fulfill 42
  end
end

o2 = o1.then do |result|
  Obligation.create do |w|
    Thread.new do
      r.fulfill result.times.map do
        Net::HTTP.get('example.com', 'index.html')
      end
    end
  end
end

o2.value #=> ["<html>...", "<html>...", ...]

Seamless integration with any library using Obligation

o1 = Obligation.create do |w|
  Thread.new do
    sleep 1 # Heavy calculation
    w.fulfill 42
  end
end

o2 = o1.then do |result|
  HTTPLibUsingObligation.get("http://example.org/#{result}.html")
end

o2.value #=> ["<html>..."]

Yields:

  • (result)

    Yield Obligations result after it is fulfilled.

Yield Parameters:

Yield Returns:

Returns:



81
82
83
# File 'lib/obligation.rb', line 81

def then
  throw NotImplementedError.new 'Obligation#then not implemented.'
end

#value(timeout) ⇒ Object

Wait for Obligation‘s result.

This method MUST block the thread of fiber until either the Obligation is fullfilled or the given timeout exceeds.

If the Obligation is already fulfilled the result MUST be returned instantly. An RejectedError MUST be raised when Obligation is rejected and a TimeoutError when waiting has timed out.

Parameters:

  • timeout (Integer)

    Timeout to wait in seconds.

Returns:

  • (Object)

    Obligation‘s result if any. Nil if rejected or timed out.

Raises:



102
103
104
# File 'lib/obligation.rb', line 102

def value(timeout)
  throw NotImplementedError.new 'Obligation#value not implemented.'
end