Sha256: e7c790d55882778c7779e23296180624f20c858fc7d036e863c3ef2540ee4ef8

Contents?: true

Size: 1.69 KB

Versions: 1

Compression:

Stored size: 1.69 KB

Contents

module Imap::Backup
  class MultiFetchFailedError < StandardError; end

  class Downloader
    attr_reader :folder
    attr_reader :serializer
    attr_reader :multi_fetch_size

    def initialize(folder, serializer, multi_fetch_size: 1)
      @folder = folder
      @serializer = serializer
      @multi_fetch_size = multi_fetch_size
    end

    def run
      uids = folder.uids - serializer.uids
      count = uids.count
      debug "#{count} new messages"
      uids.each_slice(multi_fetch_size).with_index do |block, i|
        uids_and_bodies = folder.fetch_multi(block)
        if uids_and_bodies.nil?
          if multi_fetch_size > 1
            debug("Multi fetch failed for UIDs #{block.join(", ")}, switching to single fetches")
            raise MultiFetchFailedError
          else
            debug("Fetch failed for UID #{block[0]} - skipping")
            next
          end
        end

        offset = i * multi_fetch_size + 1
        uids_and_bodies.each.with_index do |uid_and_body, j|
          uid = uid_and_body[:uid]
          body = uid_and_body[:body]
          case
          when !body
            info("Fetch returned empty body - skipping")
          when !uid
            info("Fetch returned empty UID - skipping")
          else
            debug("uid: #{uid} (#{offset + j}/#{count}) - #{body.size} bytes")
            serializer.append uid, body
          end
        end
      end
    rescue MultiFetchFailedError
      @multi_fetch_size = 1
      retry
    end

    private

    def info(message)
      Imap::Backup::Logger.logger.info("[#{folder.name}] #{message}")
    end

    def debug(message)
      Imap::Backup::Logger.logger.debug("[#{folder.name}] #{message}")
    end
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
imap-backup-6.0.0.rc2 lib/imap/backup/downloader.rb