raft_log/raft_log/dump.rs
1use std::io;
2use std::sync::Arc;
3
4use chunked_wal::ChunkedWal;
5use chunked_wal::WalLock;
6
7use crate::ChunkId;
8use crate::Config;
9use crate::RaftLog;
10use crate::RaftLogRecord;
11use crate::RaftWalTypes;
12use crate::Types;
13use crate::raft_log::dump_api::DumpApi;
14use crate::types::Segment;
15
16/// A dump utility that reads WAL records from disk.
17///
18/// It acquires an exclusive lock on the directory to prevent concurrent writes
19/// while reading.
20pub struct Dump<T> {
21 config: Arc<Config>,
22
23 /// Holds the WAL directory lock while reading files from disk.
24 _wal_lock: WalLock,
25
26 _p: std::marker::PhantomData<T>,
27}
28
29impl<T: Types> DumpApi<T> for Dump<T> {
30 /// Reads all WAL records from disk and passes them to the provided callback
31 /// function.
32 ///
33 /// The callback receives:
34 /// - `chunk_id`: The ID of the chunk containing the record
35 /// - `index`: The 0-based index of the record within its chunk
36 /// - `result`: The result containing either the record data or an IO error
37 ///
38 /// # Errors
39 /// Returns an IO error if reading the chunks fails or if the callback
40 /// returns an error.
41 fn write_with<D>(&self, write_record: D) -> Result<(), io::Error>
42 where D: FnMut(
43 ChunkId,
44 u64,
45 Result<(Segment, RaftLogRecord<T>), io::Error>,
46 ) -> Result<(), io::Error> {
47 ChunkedWal::<RaftWalTypes<T>>::dump_records(
48 &self.config.wal,
49 &self._wal_lock,
50 write_record,
51 )
52 }
53}
54
55/// A dump utility that reads WAL records from an existing RaftLog instance.
56///
57/// Unlike [`Dump`], this does not acquire a directory lock since it operates on
58/// an already initialized RaftLog.
59pub struct RefDump<'a, T: Types> {
60 pub(crate) raft_log: &'a RaftLog<T>,
61}
62
63impl<T: Types> DumpApi<T> for RefDump<'_, T> {
64 /// Reads all WAL records from the RaftLog and passes them to the provided
65 /// callback function.
66 ///
67 /// The callback receives:
68 /// - `chunk_id`: The ID of the chunk containing the record
69 /// - `index`: The 0-based index of the record within its chunk
70 /// - `result`: The result containing either the record data or an IO error
71 ///
72 /// # Errors
73 /// Returns an IO error if reading the chunks fails or if the callback
74 /// returns an error.
75 fn write_with<D>(&self, write_record: D) -> Result<(), io::Error>
76 where D: FnMut(
77 ChunkId,
78 u64,
79 Result<(Segment, RaftLogRecord<T>), io::Error>,
80 ) -> Result<(), io::Error> {
81 self.raft_log.wal.dump_loaded_records(write_record)
82 }
83}
84
85impl<T: Types> Dump<T> {
86 /// Creates a new Dump instance with the given configuration.
87 ///
88 /// # Errors
89 /// Returns an IO error if acquiring the directory lock fails.
90 pub fn new(config: Arc<Config>) -> Result<Self, io::Error> {
91 let wal_lock =
92 ChunkedWal::<RaftWalTypes<T>>::acquire_lock(&config.wal)?;
93
94 Ok(Self {
95 config,
96 _wal_lock: wal_lock,
97 _p: std::marker::PhantomData,
98 })
99 }
100}