Class: OpenASN::Dataset
- Inherits:
-
Object
- Object
- OpenASN::Dataset
- Defined in:
- lib/openasn/dataset.rb
Overview
Owns the live Snapshot and its lifecycle. Concurrency model (the whole point of this class — do not "simplify" it):
* Readers call #snapshot and get whatever is current. The swap is a
single ivar assignment — atomic under MRI's GVL — so readers see
either the old complete snapshot or the new complete snapshot,
never partial state. No locks on the read path, ever.
* The lazy first load and explicit reloads are serialized with a
Mutex so N threads arriving on a cold process build one snapshot,
not N.
* Multi-process reality (puma workers): the updater process writes
new files atomically; OTHER processes notice via a cheap periodic
freshness probe (#maybe_reload_from_disk — a File.mtime call at
most every RELOAD_CHECK_INTERVAL seconds, amortized to ~zero) and
rebuild their in-memory snapshot from disk.
Constant Summary collapse
- RELOAD_CHECK_INTERVAL =
seconds
300- STALE_AFTER =
boot-time "kick a refresh" threshold (documented in README "Updates")
7 * 86_400
Instance Method Summary collapse
- #eager_load! ⇒ Object
- #info ⇒ Object
-
#initialize(config) ⇒ Dataset
constructor
A new instance of Dataset.
- #loaded? ⇒ Boolean
-
#reload! ⇒ Object
Called by the updater after it wrote new files: rebuild + swap now.
- #snapshot ⇒ Object
- #stale? ⇒ Boolean
Constructor Details
#initialize(config) ⇒ Dataset
Returns a new instance of Dataset.
23 24 25 26 27 28 29 |
# File 'lib/openasn/dataset.rb', line 23 def initialize(config) @config = config @snapshot = nil @load_mutex = Mutex.new @last_disk_check = 0.0 @loaded_manifest_mtime = nil end |
Instance Method Details
#eager_load! ⇒ Object
38 39 40 41 |
# File 'lib/openasn/dataset.rb', line 38 def eager_load! load! nil end |
#info ⇒ Object
60 61 62 63 64 65 66 67 68 69 70 71 |
# File 'lib/openasn/dataset.rb', line 60 def info snap = snapshot { build_id: snap.build_id, built_at: Time.at(snap.build_ts).utc, loaded_at: snap.loaded_at, origin: snap.origin, memory_mode: @config.memory_mode, records: snap.record_counts, tier_b_status: snap.tier_b_status } end |
#loaded? ⇒ Boolean
53 |
# File 'lib/openasn/dataset.rb', line 53 def loaded? = !@snapshot.nil? |
#reload! ⇒ Object
Called by the updater after it wrote new files: rebuild + swap now.
44 45 46 47 48 49 50 51 |
# File 'lib/openasn/dataset.rb', line 44 def reload! @load_mutex.synchronize do @snapshot = Snapshot.build(@config) @loaded_manifest_mtime = manifest_mtime @last_disk_check = monotonic_now @snapshot end end |
#snapshot ⇒ Object
31 32 33 34 35 36 |
# File 'lib/openasn/dataset.rb', line 31 def snapshot snap = @snapshot return snap if snap && !disk_check_due? snap ? maybe_reload_from_disk : load! end |
#stale? ⇒ Boolean
55 56 57 58 |
# File 'lib/openasn/dataset.rb', line 55 def stale? snap = snapshot snap.age_seconds > STALE_AFTER end |