Module: AWS::Flow::Utilities

Defined in:
lib/aws/decider/utilities.rb

Overview

Utilities for the AWS Flow Framework for Ruby.

Defined Under Namespace

Modules: SelfMethods, UpwardLookups Classes: AddressableFuture, LogFactory

Class Method Summary collapse

Class Method Details

.activity_task_to_debug_string(message, task) ⇒ Object



43
44
45
46
# File 'lib/aws/decider/utilities.rb', line 43

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

.check_and_truncate_exception(error, converter) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

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



98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
# File 'lib/aws/decider/utilities.rb', line 98

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) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/aws/decider/utilities.rb', line 81

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) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



64
65
66
67
68
69
# File 'lib/aws/decider/utilities.rb', line 64

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) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
# File 'lib/aws/decider/utilities.rb', line 169

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_externalObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



222
223
224
225
226
227
228
229
# File 'lib/aws/decider/utilities.rb', line 222

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) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



72
73
74
75
76
77
78
# File 'lib/aws/decider/utilities.rb', line 72

def self.merge_all_options(*args)
  args.compact!
  youngest = args.last
  args.delete(youngest)
  youngest.precursors.concat(args.reverse)
  youngest.get_full_options
end

.validation_error_string(infix) ⇒ Object



58
59
60
61
# File 'lib/aws/decider/utilities.rb', line 58

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) ⇒ Object

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



50
51
52
53
54
55
56
# File 'lib/aws/decider/utilities.rb', line 50

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) ⇒ Object



36
37
38
39
40
41
# File 'lib/aws/decider/utilities.rb', line 36

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