class Restforce::DB::TaskManager

Restforce::DB::TaskManager defines the run sequence and invocation of each of the Restforce::DB::Task subclasses during a single processing loop for the top-level Worker object.

Public Class Methods

new(runner, logger: nil) click to toggle source

Public: Initialize a new Restforce::DB::TaskManager for a given runner state.

runner - A Restforce::DB::Runner for a specific period of time. logger - A Logger object (optional).

# File lib/restforce/db/task_manager.rb, line 32
def initialize(runner, logger: nil)
  @runner = runner
  @logger = logger
  @changes = Hash.new { |h, k| h[k] = Accumulator.new }
end

Public Instance Methods

perform() click to toggle source

Public: Run each of the sync tasks in a defined order for the supplied runner's current state.

Returns nothing.

# File lib/restforce/db/task_manager.rb, line 42
def perform
  Registry.each do |mapping|
    run("CLEANING RECORDS", Cleaner, mapping)
    run("ATTACHING RECORDS", Attacher, mapping)
    run("PROPAGATING RECORDS", Initializer, mapping)
    run("COLLECTING CHANGES", Collector, mapping)
  end

  # NOTE: We can only perform the synchronization after all record changes
  # have been aggregated, so this second loop is necessary.
  Registry.each do |mapping|
    run("UPDATING ASSOCIATIONS", Associator, mapping)
    run("APPLYING CHANGES", Synchronizer, mapping)
  end
end

Private Instance Methods

run(name, task_class, mapping) click to toggle source

Internal: Log a description and response time for a specific named task.

NOTE: AuthenticationErrors from Restforce's middleware seem to be linked to thread-safety issues, so we want to error out the entire processing loop in the event that we run into one of these. This is the reason for the fairly convoluted `rescue` chain below.

name - A String task name. task_class - A Restforce::DB::Task subclass. mapping - A Restforce::DB::Mapping.

Returns a Boolean.

# File lib/restforce/db/task_manager.rb, line 72
def run(name, task_class, mapping)
  log "  #{name} between #{mapping.database_model.name} and #{mapping.salesforce_model}"
  runtime = Benchmark.realtime { task task_class, mapping }
  log format("  FINISHED #{name} after %.4f", runtime)

  true
rescue Restforce::AuthenticationError => e
  log e, :warn
  raise e
rescue => e
  error(e)
  false
rescue Exception => e # rubocop:disable Lint/RescueException
  error(e)
  raise e
end
task(task_class, mapping) click to toggle source

Internal: Run the passed mapping through the supplied Task class.

task_class - A Restforce::DB::Task subclass. mapping - A Restforce::DB::Mapping.

Returns nothing.

# File lib/restforce/db/task_manager.rb, line 95
def task(task_class, mapping)
  task_class.new(mapping, @runner).run(@changes)
rescue Faraday::Error::ClientError => e
  task_mapping = TaskMapping.new(task_class, mapping)
  error SynchronizationError.new(e, task_mapping)
end