Sha256: 21630ee45baf3a72d08356e02feaac1960b86bad3bd1af5f29a729bb8b80e64d

Contents?: true

Size: 1.61 KB

Versions: 1

Compression:

Stored size: 1.61 KB

Contents

require "tlopo/retry/version"
require 'logger'
require 'timeout'

module Tlopo
  LOGGER ||= proc do 
    logger = Logger.new(ENV['TLOPO_LOG_LEVEL'] ? STDERR : '/dev/null')
    logger.level = ENV['TLOPO_LOG_LEVEL'] ? "#{ENV['TLOPO_LOG_LEVEL'].upcase}" :  Logger::ERROR
    logger
  end.call
  
end

module Tlopo::Retry 
  LOGGER = Tlopo::LOGGER
  LOGGER.debug "#{self} loaded"
  def self.retry(opts={},&block)
    is_fork = opts[:fork]
    return local(opts,&block) unless is_fork
    return child(opts,&block) if is_fork
  end

  private 
  def self.child(opts={},&block)
    read, write = IO.pipe
  
    pid = fork do
      read.close
      begin 
        result = local(opts,&block)
        Marshal.dump({result: result, error: nil}, write)
      rescue => e
        Marshal.dump({result:nil, error: e},write)
      end
    end
  
    write.close
    result = Marshal.load(read.read)
    Process.wait(pid)
    raise result[:error] if result[:error]
    result[:result]
  end

  def self.local(opts={},&block)
    tries = opts[:tries] || 3
    timeout = opts[:timeout] || 0
    interval = opts[:interval] || 1
    desc = opts[:desc]
    cleanup = opts[:cleanup] 
    LOGGER.debug "opts: #{opts}"
    LOGGER.debug "tries: #{tries}"
    count = 0
    begin
      count += 1
      Timeout::timeout(timeout) { yield }
    rescue => e 
      unless count > tries 
        msg = "#{self} Retrying to #{desc} #{count} out of #{tries}"
        LOGGER.info msg if desc
        LOGGER.debug "#{self} Calling cleanup" if cleanup
        cleanup.call if cleanup
        sleep interval
        retry 
      else
        raise e
      end
    end
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
tlopo-retry-0.1.0 lib/tlopo/retry.rb