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
}

Instance Method Summary collapse

Constructor Details

#initialize(params = {}) ⇒ ResumePolicy



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

def initialize(params={})
  @parameters=DEFAULTS.clone
  return if params.nil?
  raise "expecting Hash (or nil), but have #{params.class}" unless params.is_a?(Hash)
  params.each do |k,v|
    if DEFAULTS.has_key?(k)
      @parameters[k]=v
    else
      raise "unknown resume parameter: #{k}, expect one of #{DEFAULTS.keys.map{|i|i.to_s}.join(",")}"
    end
  end
end

Instance Method Details

#process(&block) ⇒ Object

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



32
33
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
# File 'lib/aspera/fasp/resume_policy.rb', line 32

def process(&block)
  # 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 succesful
  loop do
    Log.log.debug('transfer starting');
    begin
      block.call
      break
    rescue Fasp::Error => e
      Log.log.warn("An error occured: #{e.message}" );
      # failure in ascp
      if e.retryable? then
        # exit if we exceed the max number of retry
        unless remaining_resumes > 0
          Log.log.error "Maximum number of retry reached"
          raise Fasp::Error,"max retry after: [#{status[:message]}]"
        end
      else
        # give one chance only to non retryable errors
        unless remaining_resumes.eql?(@parameters[:iter_max])
          Log.log.error('non-retryable error')
          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