Class: DynamicImage::Backfill

Inherits:
Object
  • Object
show all
Defined in:
lib/dynamic_image/backfill.rb

Overview

DynamicImage Backfill

Fills in the metadata columns for records stored before those columns existed. The values are read back from the stored file, except where the format guarantees them.

Records are written with update_columns, so no callbacks run and updated_at is left alone. Model#to_param fingerprints on updated_at, and touching it would invalidate every image URL and every cached variant.

DynamicImage::Backfill.new(Image).run

See Also:

Constant Summary collapse

COLUMNS =

The columns this fills in.

%i[frame_count alpha].freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(model, concurrency: 4) ⇒ Backfill

Returns a new instance of Backfill.

Parameters:

  • model (Class)

    a model including Model

  • concurrency (Integer) (defaults to: 4)

    how many files to read at a time. Reads are network bound; the metadata itself comes off the header. Set to 1 to read serially.



32
33
34
35
36
37
38
# File 'lib/dynamic_image/backfill.rb', line 32

def initialize(model, concurrency: 4)
  @model = model
  @updated = 0
  @skipped = 0
  @inferred = 0
  @concurrency = [concurrency.to_i, 1].max
end

Instance Attribute Details

#inferredInteger (readonly)

Returns records filled in from the format, without a read.

Returns:

  • (Integer)

    records filled in from the format, without a read



27
28
29
# File 'lib/dynamic_image/backfill.rb', line 27

def inferred
  @inferred
end

#skippedInteger (readonly)

Returns records left alone, unreadable or missing.

Returns:

  • (Integer)

    records left alone, unreadable or missing



24
25
26
# File 'lib/dynamic_image/backfill.rb', line 24

def skipped
  @skipped
end

#updatedInteger (readonly)

Returns records written.

Returns:

  • (Integer)

    records written



21
22
23
# File 'lib/dynamic_image/backfill.rb', line 21

def updated
  @updated
end

Instance Method Details

#pendingActiveRecord::Relation

The records with a column still unset.

Returns:

  • (ActiveRecord::Relation)

    the pending records



43
44
45
# File 'lib/dynamic_image/backfill.rb', line 43

def pending
  COLUMNS.map { |column| model.where(column => nil) }.reduce(:or)
end

#run {|record| ... } ⇒ self

Fills in what the format settles, then reads the rest.

Yield Parameters:

Returns:

  • (self)

Raises:

  • (ArgumentError)

    if the table doesn't have the columns yet



52
53
54
55
56
57
58
59
60
61
62
# File 'lib/dynamic_image/backfill.rb', line 52

def run
  ensure_columns
  infer_from_format
  pending.find_in_batches(batch_size: concurrency) do |batch|
    read(batch).each do |record, values|
      write(record, values)
      yield(record) if block_given?
    end
  end
  self
end