Class: RailsWayback::CacheInventory

Inherits:
Object
  • Object
show all
Defined in:
lib/rails_wayback/cache_inventory.rb

Overview

Reads cache metadata and applies explicit LRU pruning policies.

Defined Under Namespace

Classes: Entry, PruneResult, Snapshot

Constant Summary collapse

MATERIALIZATION_VERSION =
"4"
METADATA_VERSION =
1
MARKER_NAME =
".rails_wayback.sha"
METADATA_NAME =
".rails_wayback.meta.json"
SHA_PATTERN =
/\A(?:[0-9a-f]{40}|[0-9a-f]{64})\z/i

Instance Method Summary collapse

Constructor Details

#initialize(configuration: RailsWayback.configuration) ⇒ CacheInventory

Returns a new instance of CacheInventory.



51
52
53
# File 'lib/rails_wayback/cache_inventory.rb', line 51

def initialize(configuration: RailsWayback.configuration)
  @configuration = configuration
end

Instance Method Details

#prune!(preserve: []) ⇒ Object

Caller must hold the cache's exclusive lock.



73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/rails_wayback/cache_inventory.rb', line 73

def prune!(preserve: [])
  preserved = Array(preserve).map(&:to_s)
  entries = snapshot.refs
  removed = remove_invalid(entries, preserved)
  remaining = entries - removed

  removable = remaining.reject { |entry| preserved.include?(entry.sha) }
                       .sort_by { |entry| [entry.last_accessed_at, entry.sha] }
  while limits_exceeded?(remaining) && removable.any?
    entry = removable.shift
    remove_entry(entry)
    removed << entry
    remaining.delete(entry)
  end

  final_snapshot = Snapshot.new(refs: remaining)
  PruneResult.new(
    removed: removed,
    snapshot: final_snapshot,
    limits_satisfied: !limits_exceeded?(remaining)
  )
end

#snapshot ⇒ Object



55
56
57
# File 'lib/rails_wayback/cache_inventory.rb', line 55

def snapshot
  Snapshot.new(refs: entry_paths.filter_map { |path| build_entry(path) })
end

#write_metadata(path, sha) ⇒ Object



59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/rails_wayback/cache_inventory.rb', line 59

def (path, sha)
  size_bytes, file_count = measure(path)
  payload = {
    metadata_version: METADATA_VERSION,
    materialization_version: MATERIALIZATION_VERSION,
    sha: sha,
    size_bytes: size_bytes,
    file_count: file_count,
    created_at: Time.now.utc.iso8601
  }
  (path).write(JSON.generate(payload))
end