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



49
50
51
52
# 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) ⇒ 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.



262
263
264
# 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) ⇒ 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.



267
268
269
270
271
272
273
# 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) ⇒ 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.



257
258
259
# 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) ⇒ 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.



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
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
# 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) ⇒ 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.



87
88
89
90
91
92
93
94
95
96
97
98
99
# 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) ⇒ 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.



70
71
72
73
74
75
# 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) ⇒ 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.



194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
# 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_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.



247
248
249
250
251
252
253
254
# 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) ⇒ 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.



78
79
80
81
82
83
84
# 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) ⇒ 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 register a domain with the Simple Workflow Service.

Parameters:

  • name

    Name of the domain

  • retention (defaults to: nil)

    Workflow execution retention period in days



106
107
108
109
110
111
112
113
114
115
116
117
118
# 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) ⇒ Object



64
65
66
67
# 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) ⇒ Object

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



56
57
58
59
60
61
62
# 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) ⇒ Object



42
43
44
45
46
47
# 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