Class: Aspera::Fasp::ResumePolicy

Inherits:
Object
  • Object
show all
Defined in:
lib/aspera/fasp/resume_policy.rb

Overview

implements a simple resume policy

Constant Summary collapse

DEFAULTS =

list of supported parameters and default values

{
  iter_max:      7,
  sleep_initial: 2,
  sleep_factor:  2,
  sleep_max:     60
}.freeze

Instance Method Summary collapse

Constructor Details

#initialize(params = nil) ⇒ ResumePolicy

Returns a new instance of ResumePolicy.

Parameters:

  • params (defaults to: nil)

    see DEFAULTS



19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/aspera/fasp/resume_policy.rb', line 19

def initialize(params=nil)
  @parameters = DEFAULTS.dup
  if !params.nil?
    raise "expecting Hash (or nil), but have #{params.class}" unless params.is_a?(Hash)
    params.each do |k, v|
      raise "unknown resume parameter: #{k}, expect one of #{DEFAULTS.keys.map(&:to_s).join(',')}" unless DEFAULTS.key?(k)
      raise "#{k} must be Integer" unless v.is_a?(Integer)
      @parameters[k] = v
    end
  end
  Log.log.debug{"resume params=#{@parameters}"}
end

Instance Method Details

#execute_with_resumeObject

calls block a number of times (resumes) until success or limit reached this is re-entrant, one resumer can handle multiple transfers in //



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/aspera/fasp/resume_policy.rb', line 34

def execute_with_resume
  raise 'block mandatory' unless block_given?
  # maximum of retry
  remaining_resumes = @parameters[:iter_max]
  sleep_seconds = @parameters[:sleep_initial]
  Log.log.debug{"retries=#{remaining_resumes}"}
  # try to send the file until ascp is successful
  loop do
    Log.log.debug('transfer starting')
    begin
      # call provided block
      yield
      break
    rescue Fasp::Error => e
      Log.log.warn{"An error occurred: #{e.message}"}
      # failure in ascp
      if e.retryable?
        # exit if we exceed the max number of retry
        raise Fasp::Error, "Maximum number of retry reached (#{@parameters[:iter_max]})" if remaining_resumes <= 0
      else
        # give one chance only to non retryable errors
        unless remaining_resumes.eql?(@parameters[:iter_max])
          Log.log.error('non-retryable error'.red.blink)
          raise e
        end
      end
    end

    # take this retry in account
    remaining_resumes -= 1
    Log.log.warn{"Resuming in #{sleep_seconds} seconds (retry left:#{remaining_resumes})"}

    # wait a bit before retrying, maybe network condition will be better
    sleep(sleep_seconds)

    # increase retry period
    sleep_seconds *= @parameters[:sleep_factor]
    # cap value
    sleep_seconds = @parameters[:sleep_max] if sleep_seconds > @parameters[:sleep_max]
  end # loop
end