wasmer_journal/concrete/
mem_file.rs1use std::{
2 fs::File,
3 io::{Seek, Write},
4 path::Path,
5 sync::RwLock,
6};
7
8use lz4_flex::{block, decompress};
9
10use super::*;
11
12#[derive(Debug)]
16pub struct MemFileJournal {
17 file: RwLock<File>,
18}
19
20impl MemFileJournal {
21 pub fn new(path: &Path) -> anyhow::Result<Self> {
22 Ok(Self {
23 file: RwLock::new(
24 std::fs::OpenOptions::new()
25 .create(true)
26 .truncate(false)
27 .write(true)
28 .open(path)?,
29 ),
30 })
31 }
32}
33
34impl Drop for MemFileJournal {
35 fn drop(&mut self) {
36 let _ = self.flush();
37 }
38}
39
40impl Clone for MemFileJournal {
41 fn clone(&self) -> Self {
42 let file = self.file.read().unwrap();
43 Self {
44 file: RwLock::new(file.try_clone().unwrap()),
45 }
46 }
47}
48
49impl ReadableJournal for MemFileJournal {
50 fn read(&self) -> anyhow::Result<Option<LogReadResult<'_>>> {
51 Ok(None)
52 }
53
54 fn as_restarted(&self) -> anyhow::Result<Box<DynReadableJournal>> {
55 Ok(Box::new(self.clone()))
56 }
57}
58
59impl WritableJournal for MemFileJournal {
60 fn write<'a>(&'a self, entry: JournalEntry<'a>) -> anyhow::Result<LogWriteResult> {
61 let estimated_size = entry.estimate_size() as u64;
62 match entry {
63 JournalEntry::UpdateMemoryRegionV1 {
64 region,
65 compressed_data,
66 } => {
67 let (uncompressed_size, compressed_data) =
68 block::uncompressed_size(&compressed_data)?;
69 let decompressed_data = decompress(compressed_data, uncompressed_size)?;
70
71 let mut file = self.file.write().unwrap();
72 file.seek(std::io::SeekFrom::Start(region.start))?;
73 file.write_all(&decompressed_data)?;
74 }
75 JournalEntry::ProcessExitV1 { .. } | JournalEntry::InitModuleV1 { .. } => {
76 let file = self.file.read().unwrap();
77 file.set_len(0)?;
78 }
79 _ => {}
80 }
81
82 Ok(LogWriteResult {
83 record_start: 0,
84 record_end: estimated_size,
85 })
86 }
87
88 fn flush(&self) -> anyhow::Result<()> {
89 let mut file = self.file.write().unwrap();
90 file.flush()?;
91 Ok(())
92 }
93}
94
95impl Journal for MemFileJournal {
96 fn split(self) -> (Box<DynWritableJournal>, Box<DynReadableJournal>) {
97 (Box::new(self.clone()), Box::new(self.clone()))
98 }
99}