class Wayfarer::Dispatcher

Creates job instances, retrieves pages and, if a URI matches a route, calls methods on the instances.

Constants

Error
Halt
Mismatch

Result types that a {Processor} operates with.

Stage

Attributes

adapter_pool[R]

@!attribute [r] adapter_pool @return [AdapterPool]

job[R]

@!attribute [r] job

Public Class Methods

new(job) click to toggle source
# File lib/wayfarer/dispatcher.rb, line 28
def initialize(job)
  @job = job
  @adapter_pool = HTTPAdapters::AdapterPool.new(job)
end

Public Instance Methods

dispatch(job, uri, is_peeking: false) click to toggle source

Dispatches this URI. Matches an URI against the rules of the job's router. If a rule matches, the page is retrieved, and the action associated with the route is called.

@param [Job] job @param [URI] uri

# File lib/wayfarer/dispatcher.rb, line 42
def dispatch(job, uri, is_peeking: false)
  action, params = job.router.route(uri)
  return Mismatch.new(uri) unless action

  params = ActiveSupport::HashWithIndifferentAccess.new(params)

  notify_observers!(DispatchedURI.new(action, uri))

  job_instance = job.new
  result = nil

  adapter_pool.with do |adapter|
    job_instance.page = adapter.fetch(uri)
    job_instance.adapter = adapter
    job_instance.params = params

    result = job_instance.public_send(action) { |peek_uri|
      begin
        unless is_peeking
          notify_observers!(Peeking.new(uri))
          result = dispatch(job, URI(peek_uri), is_peeking: true)
          result.ret_val
        end
      rescue
        nil
      end
    }
  end

  if job_instance.halts?
    Halt.new(uri, action)
  else
    Stage.new(job_instance.staged_uris, result)
  end
# What follows are exceptions whose origin I don't care about at the moment
# TODO: Better logging
rescue Net::HTTP::Persistent::Error
  logger.warn("Net::HTTP::Persistent::Error @ #{uri}")
rescue Errno::EHOSTUNREACH
  logger.warn("Host unreachable @ #{uri}")
rescue Errno::ENETUNREACH
  logger.warn("No route to network present @ #{uri}")
rescue Net::OpenTimeout, Net::ReadTimeout
  logger.warn("::Net timeout @ #{uri}")

# SSL verification failed due to a missing certificate
rescue OpenSSL::SSL::SSLError
  logger.warn("SSL verification failed @ #{uri}")

# Ruby/zlib encountered a Z_DATA_ERROR.
# Usually if a stream was prematurely freed.
# Probably has to do with net-http-persistent?
rescue Zlib::DataError
  logger.warn("Z_DATA_ERROR")
rescue HTTPAdapters::NetHTTPAdapter::MalformedURI, URI::InvalidURIError
  logger.info("[warn#{self}] Malformed URI @ #{uri}")
rescue HTTPAdapters::NetHTTPAdapter::MalformedRedirectURI
  logger.info("Malformed redirect URI @ #{uri}")
rescue HTTPAdapters::NetHTTPAdapter::MaximumRedirectCountReached
  logger.info("Maximum redirect count reached @ #{uri}")
end