msgpack_tracing/
rotate.rs

1use crate::{
2    storage::Store,
3    string_cache::{CacheInstruction, CacheInstructionSet},
4    tape::{Instruction, InstructionSet, TapeMachine},
5};
6use std::{
7    fs::File,
8    io::{self, Seek},
9    path::{Path, PathBuf},
10    time::Duration,
11};
12
13pub struct Rotate {
14    file: Option<File>,
15    path: PathBuf,
16    path1: Option<PathBuf>,
17    max_len: u64,
18}
19impl Rotate {
20    pub fn new<P: AsRef<Path>>(path: P, max_len: u64) -> io::Result<Self> {
21        let file = File::options().append(true).create(true).open(&path)?;
22        let path1 = path
23            .as_ref()
24            .to_str()
25            .map(|str| PathBuf::from(format!("{str}.1")));
26
27        Ok(Self {
28            file: Some(file),
29            path: path.as_ref().to_owned(),
30            path1,
31            max_len,
32        })
33    }
34
35    pub fn file_mut(&mut self) -> io::Result<&mut File> {
36        self.file
37            .as_mut()
38            .ok_or_else(|| io::Error::new(io::ErrorKind::BrokenPipe, "file closed"))
39    }
40
41    pub fn do_needs_restart(&mut self) -> io::Result<bool> {
42        let max_len = self.max_len;
43        let file = self.file_mut()?;
44
45        if file.stream_position()? <= max_len {
46            return Ok(false);
47        }
48
49        std::thread::sleep(Duration::from_secs(1));
50        self.file = None;
51
52        if let Some(path1) = self.path1.as_ref() {
53            std::fs::rename(&self.path, path1)?;
54        }
55        self.file = Some(File::create(&self.path)?);
56
57        Ok(true)
58    }
59}
60impl TapeMachine<CacheInstructionSet> for Rotate {
61    fn needs_restart(&mut self) -> bool {
62        self.do_needs_restart().unwrap_or_default()
63    }
64
65    fn handle(&mut self, instruction: CacheInstruction) {
66        let Ok(file) = self.file_mut() else {
67            return;
68        };
69
70        let _ = Store::do_handle_cached(file, instruction);
71    }
72}
73impl TapeMachine<InstructionSet> for Rotate {
74    fn needs_restart(&mut self) -> bool {
75        self.do_needs_restart().unwrap_or_default()
76    }
77
78    fn handle(&mut self, instruction: Instruction) {
79        let Ok(file) = self.file_mut() else {
80            return;
81        };
82
83        let _ = Store::do_handle(file, instruction);
84    }
85}