msgpack_tracing/
rotate.rs1use 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}