Class: OpenASN::Updater

Inherits:
Object
  • Object
show all
Defined in:
lib/openasn/updater.rb

Overview

The data refresh cycle (what OpenASN.update! / UpdateJob runs):

1. Canonical: GET {release_url}manifest.json (ETag-conditional).
 When it changed, download each artifact, VERIFY ITS SHA-256
 against the manifest, write to *.tmp, File.rename into place
 (atomic on POSIX — a crashed update can never leave a torn file),
 then write manifest.json LAST — it is the commit marker other
 processes watch for (Dataset#maybe_reload_from_disk).
2. Tier B: execute the fetch-manifest for enabled sources (TierB).
 Per-source failures keep stale data and never fail the update.
3. Swap the in-process snapshot.

Concurrency: a non-blocking flock serializes updaters across processes (first puma worker wins; the rest skip — they'll pick up the files via the freshness probe). Never raises for "someone else is updating".

Constant Summary collapse

CANONICAL_FILES =
%w[openasn-ipv4.bin openasn-ipv6.bin openasn-orgs.bin].freeze

Instance Method Summary collapse

Constructor Details

#initialize(config, dataset) ⇒ Updater

Returns a new instance of Updater.



26
27
28
29
30
31
# File 'lib/openasn/updater.rb', line 26

def initialize(config, dataset)
  @config = config
  @dataset = dataset
  @http = HttpClient.new(user_agent: config.user_agent, logger: config.logger)
  @logger = config.logger
end

Instance Method Details

#run(force: false) ⇒ Object

-> :updated | :tier_b_only | :unchanged | :locked



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/openasn/updater.rb', line 34

def run(force: false)
  FileUtils.mkdir_p(@config.data_dir)
  with_lock do
    canonical_changed = refresh_canonical(force: force)
    tier_b_changed = TierB.new(@config, @http).execute(force: force)

    if canonical_changed || tier_b_changed
      @dataset.reload!
      notify(canonical_changed ? :updated : :tier_b_only)
      canonical_changed ? :updated : :tier_b_only
    else
      :unchanged
    end
  end
end