Module: Igniter::Store::NativeFileBackendSnapshotSupport
Overview
Patch native FileBackend to add snapshot support. The native class exposes write_fact, replay (WAL-only), and close. We add: write_snapshot, snapshot_path, SNAPSHOT_SUFFIX, and a snapshot-aware replay that merges snapshot facts with the WAL delta.
Deduplication uses the original fact id embedded in the snapshot JSON (not the id on the reconstructed Fact object, which is regenerated by Fact.build in native mode).
Constant Summary collapse
- SNAPSHOT_SUFFIX =
".snap"
Constants included from WireProtocol
WireProtocol::FRAME_CRC_SIZE, WireProtocol::FRAME_HEADER_SIZE
Instance Method Summary collapse
-
#replace_with_snapshot!(facts) ⇒ Object
Pruning-safe barrier for native-backed stores.
-
#replay ⇒ Object
Merges snapshot facts (if any) with WAL facts not already in the snapshot.
- #snapshot_path ⇒ Object
- #write_snapshot(facts) ⇒ Object
Methods included from WireProtocol
Instance Method Details
#replace_with_snapshot!(facts) ⇒ Object
Pruning-safe barrier for native-backed stores. Writes the snapshot atomically, then truncates the WAL file so that dropped facts cannot be replayed on reopen. The native write handle is still open; after truncation, the next native write will restart from offset 0 (append mode semantics).
182 183 184 185 |
# File 'lib/igniter/store/file_backend.rb', line 182 def replace_with_snapshot!(facts) write_snapshot(facts) File.open(@_ruby_path, "wb") {} # truncate WAL end |
#replay ⇒ Object
Merges snapshot facts (if any) with WAL facts not already in the snapshot. Deduplication is by original id read directly from the JSON frame, because Fact.from_h in native mode regenerates ids via Fact.build.
204 205 206 207 208 209 |
# File 'lib/igniter/store/file_backend.rb', line 204 def replay snapshot_facts, seen_ids = load_native_snapshot wal_facts = _native_replay_wal delta = wal_facts.reject { |f| seen_ids.include?(f.id) } snapshot_facts + delta end |
#snapshot_path ⇒ Object
173 174 175 |
# File 'lib/igniter/store/file_backend.rb', line 173 def snapshot_path @_ruby_path + SNAPSHOT_SUFFIX end |
#write_snapshot(facts) ⇒ Object
187 188 189 190 191 192 193 194 195 196 197 198 199 |
# File 'lib/igniter/store/file_backend.rb', line 187 def write_snapshot(facts) tmp = "#{snapshot_path}.tmp" File.open(tmp, "wb") do |f| header = JSON.generate({ type: "snapshot_header", fact_count: facts.size, written_at: Process.clock_gettime(Process::CLOCK_REALTIME) }) f.write(encode_frame(header)) facts.each { |fact| f.write(encode_frame(JSON.generate(fact.to_h))) } end FileUtils.mv(tmp, snapshot_path) end |