Class: Aspera::Transfer::Resumer

Inherits:
Object
  • Object
show all
Defined in:
lib/aspera/transfer/resumer.rb

Overview

Implements a simple resume policy

Instance Method Summary collapse

Constructor Details

#initialize(iter_max: 7, sleep_initial: 2, sleep_factor: 2, sleep_max: 60) ⇒ Resumer

Returns a new instance of Resumer.

Parameters:

  • iter_max (Integer) (defaults to: 7)

    Maximum number of executions

  • sleep_initial (Integer) (defaults to: 2)

    Initial wait to re-execute

  • sleep_factor (Integer) (defaults to: 2)

    Multiplier

  • sleep_max. (Integer)

    Max iterations



16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/aspera/transfer/resumer.rb', line 16

def initialize(
  iter_max: 7,
  sleep_initial: 2,
  sleep_factor:  2,
  sleep_max:     60
)
  Aspera.assert_type(iter_max, Integer){k}
  @iter_max = iter_max
  Aspera.assert_type(sleep_initial, Integer){k}
  @sleep_initial = sleep_initial
  Aspera.assert_type(sleep_factor, Integer){k}
  @sleep_factor = sleep_factor
  Aspera.assert_type(sleep_max, Integer){k}
  @sleep_max = sleep_max
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 //

Parameters:

  • block (Proc)


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
# File 'lib/aspera/transfer/resumer.rb', line 36

def execute_with_resume
  Aspera.assert(block_given?)
  # maximum of retry
  remaining_resumes = @iter_max
  sleep_seconds = @sleep_initial
  Log.log.debug{"retries=#{remaining_resumes}"}
  # try to send the file until ascp is successful
  loop do
    Log.log.debug('Transfer session starting')
    begin
      # Call provided block: execute transfer
      yield
      # Exit retry loop if success
      break
    rescue Error => e
      Log.log.warn{"A transfer error occurred during transfer: #{e.message}"}
      Log.log.debug{"Retryable ? #{e.retryable?}"}
      # do not retry non-retryable
      raise unless e.retryable?
      # exit if we exceed the max number of retry
      raise Error, "Maximum number of retry reached: #{@iter_max}" if remaining_resumes <= 0
    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 *= @sleep_factor
    # cap value
    sleep_seconds = @sleep_max if sleep_seconds > @sleep_max
  end
end