Class: Chewy::Index::Import::Progressbar

Inherits:
Object
  • Object
show all
Defined in:
lib/chewy/index/import/progressbar.rb

Overview

Thin wrapper around ‘ruby-progressbar` for import feedback.

Unlike the original PR #787 implementation, this wrapper is only touched from the parent process: serial imports increment it directly, and parallel imports increment it via ‘Parallel`’s ‘finish:` callback (which runs in the parent under an internal mutex). The workers stay process-based, so there is no GVL contention as in PR #787 / #800.

‘Progressbar.build` returns a NULL object when the feature is disabled, so call sites do not need feature guards.

Constant Summary collapse

NULL =
Object.new
BOUNDED_FORMAT =
'%t |%B| %p%% %c/%C %e'.freeze
UNBOUNDED_FORMAT =
'%t %c (%a)'.freeze
TITLE =
'Importing'.freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(total = nil) ⇒ Progressbar

Returns a new instance of Progressbar.



54
55
56
57
# File 'lib/chewy/index/import/progressbar.rb', line 54

def initialize(total = nil)
  format = total ? BOUNDED_FORMAT : UNBOUNDED_FORMAT
  @bar = ::ProgressBar.create(title: TITLE, total: total, format: format)
end

Instance Attribute Details

#barObject (readonly)

Returns the value of attribute bar.



52
53
54
# File 'lib/chewy/index/import/progressbar.rb', line 52

def bar
  @bar
end

Class Method Details

.build(enabled, total) ⇒ Progressbar, NULL

Parameters:

  • enabled (Boolean, :unbounded)

    feature flag. ‘:unbounded` shows a spinner with no total (skip `import_count`).

  • total (Integer, nil)

    expected total; ignored when ‘:unbounded`.

Returns:



30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/chewy/index/import/progressbar.rb', line 30

def self.build(enabled, total)
  return NULL unless enabled

  unless '::ProgressBar'.safe_constantize
    raise 'The `ruby-progressbar` gem is required for import progress, ' \
          "please add `gem 'ruby-progressbar'` to your Gemfile"
  end

  return new if enabled == :unbounded

  new(normalize_total(total))
end

.normalize_total(total) ⇒ Object

Some ActiveRecord scopes (e.g., ‘.group(…)`) make `.count` return a Hash rather than an Integer. Coerce so we still get a usable total.



45
46
47
48
49
50
# File 'lib/chewy/index/import/progressbar.rb', line 45

def self.normalize_total(total)
  case total
  when Hash then total.values.sum
  when Integer then total
  end
end

Instance Method Details

#finishObject



73
74
75
# File 'lib/chewy/index/import/progressbar.rb', line 73

def finish
  bar.finish unless bar.finished?
end

#increment(by) ⇒ Object

Clamps to total when bounded — action_objects may include :delete entries (parent-child re-indexing, delete_if scope) that aren’t counted by ‘adapter.import_count`, which would otherwise raise ProgressBar::InvalidProgressError.



63
64
65
66
67
# File 'lib/chewy/index/import/progressbar.rb', line 63

def increment(by)
  target = bar.progress + by
  target = [bar.total, target].min if bar.total
  bar.progress = target
end

#total=(value) ⇒ Object



69
70
71
# File 'lib/chewy/index/import/progressbar.rb', line 69

def total=(value)
  bar.total = value
end