module AWS::Flow::Utilities

Utilities for the AWS Flow Framework for Ruby.

Public Class Methods

activity_task_to_debug_string(message, task) click to toggle source
# File lib/aws/decider/utilities.rb, line 49
def self.activity_task_to_debug_string(message, task)
  "#{message} #{task.activity_type.name}.#{task.activity_type.version} "\
  "with input: #{task.input} and task_token: #{task.task_token}"
end
add_activity_worker_to_spec(spec, klass, tasklist) click to toggle source

@api private

# File lib/aws/decider/utilities.rb, line 262
def self.add_activity_worker_to_spec(spec, klass, tasklist)
  add_worker_to_spec(spec, 'activity', klass, tasklist)
end
add_worker_to_spec(spec, type, klass, tasklist) click to toggle source

@api private

# File lib/aws/decider/utilities.rb, line 267
def self.add_worker_to_spec(spec, type, klass, tasklist)
  spec["#{type}_workers"] << {
    "#{type}_classes" => ["#{klass}"],
    "task_list" => "#{tasklist}"
  }
  spec
end
add_workflow_worker_to_spec(spec, klass, tasklist) click to toggle source

@api private

# File lib/aws/decider/utilities.rb, line 257
def self.add_workflow_worker_to_spec(spec, klass, tasklist)
  add_worker_to_spec(spec, 'workflow', klass, tasklist)
end
check_and_truncate_exception(error, converter) click to toggle source

This method is used to truncate Activity and Workflow exceptions to fit them into responses to the SWF service. @api private

# File lib/aws/decider/utilities.rb, line 123
def self.check_and_truncate_exception error, converter

  # serialize the exception so that we can check the actual size of the
  # payload.
  converted_failure = converter.dump(error)
  # get the reason/message of the exception
  reason = error.message

  # truncate the reason if needed and add a smaller version of the
  # truncation string at the end
  if reason.size > FlowConstants::REASON_LIMIT
    # saving some space at the end to add the truncation string
    reason = reason.slice(0, FlowConstants::REASON_LIMIT - FlowConstants::TRUNCATED.size)
    reason += FlowConstants::TRUNCATED
  end

  if converted_failure.to_s.size > FlowConstants::DETAILS_LIMIT
    detail_limit = FlowConstants::DETAILS_LIMIT - (reason.size + FlowConstants::TRUNCATION_OVERHEAD)
    # Get the exception details if the exception is from the flow family of
    # exceptions
    details = error.details if error.respond_to? :details
    # If you don't have details, you must be some other type of
    # exception. We can't do anything exceedingly clever, so lets just get
    # the stack trace and pop that out.
    details ||= error.backtrace.join unless error.backtrace.nil?
    details ||= ""

    # If the exception was indeed a flow family of exceptions, then details
    # inside would most likely be another exception. Instead of digging for
    # more exceptions inside this one, let's just get all the information
    # from this class and put it in a string so that we can truncate and
    # serialize it.
    if details.is_a? Exception
      details = "exception.class=#{details.class}|exception.message=#{details.message}|exception.backtrace=#{details.backtrace}"
      if details.respond_to? :details
        details += "|exception.details=#{details.details}"
      end
    end

    # truncate the details if needed and add truncation string at the end
    if details.size > detail_limit
      # saving some space at the end to add the truncation string
      details = details.slice(0, detail_limit - FlowConstants::TRUNCATED.size)
      details += FlowConstants::TRUNCATED
    end

    # Here we generate a new exception with the reason and details that we
    # got above. We are using the 'exception' factory method instead of
    # initializing it directly because Flow Exceptions' constructors are not
    # uniform and could require 2..4 arguments. Whereas a regular ruby
    # exception only requires 0..1. Other custom exceptions could require
    # arbitrary number of arguments.
    new_exception = error.exception(reason)
    if new_exception.respond_to? :details
      new_exception.details = details
    else
      new_exception.set_backtrace(details)
    end
    converted_failure = converter.dump(new_exception)

  end

  # Return back both - reason and exception so that the caller doesn't
  # need to check whether this exception responds to :reason or not, i.e.
  # whether this is a flow exception or a regular ruby exception
  [reason, converted_failure]

end
client_options_from_method_name(method_name, options) click to toggle source

@api private

# File lib/aws/decider/utilities.rb, line 87
def self.client_options_from_method_name(method_name, options)
  client_options = options.dup
  if method_name.nil?
    client_options.precursors = options.precursors.empty? ? [] : [options.precursors.first]
  else
    client_options.precursors = options.precursors.select { |x| x.name.split(".").last.to_sym == method_name }
  end

  unless options.precursors.empty?
    client_options.precursors.map!(&:options)
  end
  client_options
end
drill_on_future(future) click to toggle source

@api private

# File lib/aws/decider/utilities.rb, line 70
def self.drill_on_future(future)
  while (future.respond_to? :is_flow_future?) && future.is_flow_future?
    future = future.get
  end
  future
end
interpret_block_for_options(option_class, block, use_defaults = false) click to toggle source

@api private

# File lib/aws/decider/utilities.rb, line 194
def self.interpret_block_for_options(option_class, block, use_defaults = false)

  return option_class.new({}, use_defaults) if block.nil?
  if block.arity <= 0
    result = block.call
    if result.is_a? Hash
      options = option_class.new(result, use_defaults)
    else
      raise "If using 0 arguments to the option configuration, you must return a hash"
    end
  else
    options = option_class.new({}, use_defaults)
    block.call(options)
  end

  if options.from_class
    # Insert into the next-to-last position, as these options should be used excepting where they might conflict with the options specified in the block
    klass = get_const(options.from_class) rescue nil
    if options.precursors.empty?
      options.precursors = klass._options
    else
      options.precursors.insert(-2, klass._options).flatten!
    end
    options.prefix_name ||= options.from_class
  end
  options
end
is_external() click to toggle source

@api private

# File lib/aws/decider/utilities.rb, line 247
def self.is_external
  if (defined? Fiber).nil?
    return true
  elsif FlowFiber.current != nil && FlowFiber.current.class != Fiber && FlowFiber.current[:decision_context] != nil
    return false
  end
  return true
end
merge_all_options(*args) click to toggle source

@api private

# File lib/aws/decider/utilities.rb, line 78
def self.merge_all_options(*args)
  args.compact!
  youngest = args.last
  args.delete(youngest)
  youngest.precursors.concat(args.reverse)
  youngest.get_full_options
end
register_domain(name, retention=nil) click to toggle source

This method is used to register a domain with the Simple Workflow Service. @param name Name of the domain @param retention Workflow execution retention period in days @api private

# File lib/aws/decider/utilities.rb, line 106
def self.register_domain(name, retention=nil)
  swf = AWS::SimpleWorkflow.new
  retention ||= FlowConstants::RETENTION_DEFAULT
  begin
    swf.client.register_domain({
      name: name.to_s,
      workflow_execution_retention_period_in_days: retention.to_s
    })
  rescue AWS::SimpleWorkflow::Errors::DomainAlreadyExistsFault => e
    # possible log an INFO/WARN if the domain already exists.
  end
  return AWS::SimpleWorkflow::Domain.new(name.to_s)
end
validation_error_string(infix) click to toggle source
# File lib/aws/decider/utilities.rb, line 64
def self.validation_error_string(infix)
  "#{self.validation_error_string_partial(infix)} You can look at the "\
    "#{infix} Worker logs to see the original response."
end
validation_error_string_partial(infix) click to toggle source

The following two methods are used to generate an error string when response size of a workflow or activity is greater than 32k.

# File lib/aws/decider/utilities.rb, line 56
def self.validation_error_string_partial(infix)
  str = infix.downcase == "workflow" ? "A" : "An"
  str += " #{infix} cannot send a response with data larger than "\
    "#{FlowConstants::DATA_LIMIT} characters. Please limit the size of the "\
    "response."
  str
end
workflow_task_to_debug_string(message, task, task_list) click to toggle source
# File lib/aws/decider/utilities.rb, line 42
def self.workflow_task_to_debug_string(message, task, task_list)
  "#{message} #{task.workflow_type.name}.#{task.workflow_type.version} "\
  "for execution with workflow_id: #{task.workflow_execution.workflow_id}, "\
  "run_id: #{task.workflow_execution.run_id}, task_list: #{task_list} with "\
  "task_token: #{task.task_token}"
end