class AWS::Flow::Core::ExternalTask

Used to bridge asynchronous execution to external asynchronous APIs or events. It is passed a block, like so:

external_task do |t|
  t.cancellation_handler { |h, cause| h.fail(cause) }
  t.initiate_task { |h| trace << :task_started; h.complete; }
end

The {ExternalTask#initiate_task} method is expected to call an external API and return without blocking. Completion or failure of the external task is reported through ExternalTaskCompletionHandle, which is passed into the initiate_task and cancellation_handler blocks. The cancellation handler, defined in the same block as the initiate_task, is used to report the cancellation of the external task.

@api private

Attributes

__context__[RW]
backtrace[RW]
block[R]
cancelled[RW]
inCancellationHandler[RW]
parent[RW]

Public Class Methods

new(options = {}, &block) click to toggle source

@api private

# File lib/aws/flow/tasks.rb, line 205
def initialize(options = {}, &block)
  @inCancellationHandler = false
  @block = block
  # TODO: What should the default value be?
  @parent = options[:parent]
  @handle = ExternalTaskCompletionHandle.new(self)
  block.call(self)
end

Public Instance Methods

alive?() click to toggle source

Part of the interface provided by fiber, has to overridden to properly reflect that an external tasks alive-ness relies on its ExternalTaskCompletionHandle.

@api private

# File lib/aws/flow/tasks.rb, line 250
def alive?
  ! @handle.completed
end
cancel(cause) click to toggle source

@api private

# File lib/aws/flow/tasks.rb, line 255
def cancel(cause)
  return if @cancelled
  return if @handle.failure != nil || @handle.completed
  @cancelled = true
  if @cancellation_task != nil
    begin
      @inCancellationHandler = true
      @cancellation_task.call(cause)
    rescue Exception => e
      if ! self.backtrace.nil?
        backtrace = AsyncBacktrace.create_from_exception(@backtrace, e)
        e.set_backtrace(backtrace.backtrace) if backtrace
      end
      @handle.failure = e
    ensure
      @inCancellationHandler = false
      if ! @handle.failure.nil?
        fail_to_parent(@handle.failure)
      elsif @handle.completed
        remove_from_parent
      end
    end
  else
    remove_from_parent
  end
end
cancellation_handler(&block) click to toggle source

Store the passed-in cancellation handler block for later reference.

@api private

# File lib/aws/flow/tasks.rb, line 285
def cancellation_handler(&block)
  @cancellation_task = lambda { |cause| block.call(@handle, cause) }
end
fail_to_parent(error) click to toggle source

Add a task that fails yourself with the suppiled error, and pass it through the parents executor.

@api private

# File lib/aws/flow/tasks.rb, line 240
def fail_to_parent(error)
  @__context__.executor << FlowFiber.new { @parent.fail(self, error) }
end
get_heirs() click to toggle source

Passes the get_heirs calls to the context, to ensure uniform handling of get_heirs

@api private

# File lib/aws/flow/tasks.rb, line 200
def get_heirs
  @__context__.get_heirs
end
initiate_task(&block) click to toggle source

Store the passed-in block for later.

@api private

# File lib/aws/flow/tasks.rb, line 292
def initiate_task(&block)
  @initiation_task = lambda { block.call(@handle) }
end
is_daemon?() click to toggle source

Will always be false, provides a common API for BeginRescueEnsure’s to ensure they are maintaining their nonDaemonHeirsCount correctly.

@api private

# File lib/aws/flow/tasks.rb, line 191
def is_daemon?
  false
end
remove_from_parent() click to toggle source

Add a task that removes yourself, and pass it through the parents executor.

@api private

# File lib/aws/flow/tasks.rb, line 232
def remove_from_parent
  @__context__.executor << FlowFiber.new { @parent.remove(self) }
end
resume() click to toggle source

From the interface provided by fiber, will execute the external task.

@api private

# File lib/aws/flow/tasks.rb, line 299
def resume
  return if @cancelled
  begin
    @cancellation_handler = @initiation_task.call
  rescue Exception => e
    backtrace = AsyncBacktrace.create_from_exception(self.backtrace, e)
    e.set_backtrace(backtrace.backtrace) if backtrace
    @parent.fail(self, e)
  end
end