use crossbeam_channel;
use std::thread;
use std::io::BufWriter;
use std::io::prelude::*;
use std::fs::OpenOptions;
use crate::flare::{SerializedSender, SerializedReceiver};
use crate::mode::LogMode;
use std::sync::{Arc, Mutex};
use std::time::Duration;
const FLUSH_INTERVAL: Duration = Duration::from_millis(1000 * 30);
pub struct FlareIoWorker {
pub thread_handle: thread::JoinHandle<()>,
pub flush_thread_handle: thread::JoinHandle<()>,
pub sender: SerializedSender,
}
impl FlareIoWorker {
pub fn new(options: FlareIoOptions) -> Self {
let file = OpenOptions::new().write(true).append(true).create(true).open(options.filename.clone()).unwrap();
let writer = Arc::new(Mutex::new(BufWriter::with_capacity(options.bufwriter_cap, file)));
let writer1 = writer.clone();
let f_handle = thread::spawn(move || {
loop {
thread::sleep(FLUSH_INTERVAL);
let mut w = writer1.lock().unwrap();
w.flush().unwrap();
}
});
let (s, r) = crossbeam_channel::unbounded();
let interface = FlareIoWorkerInterface::new(r.clone());
let handle = thread::spawn(move || {
loop {
let writer = writer.clone();
let stringentry = interface.receiver.recv().unwrap();
match options.mode {
LogMode::File => {
let mut w = writer.lock().unwrap();
let _ = w.write(stringentry.as_bytes());
let _ = w.write(&[b'\n']);
},
LogMode::TerminalAndFile => {
let mut w = writer.lock().unwrap();
let _ = w.write(stringentry.as_bytes());
let _ = w.write(&[b'\n']);
println!("{}", stringentry);
},
}
}
});
Self {
thread_handle: handle,
flush_thread_handle: f_handle,
sender: s,
}
}
}
#[derive(Default)]
pub struct FlareIoOptions {
pub mode: LogMode,
pub filename: String,
pub bufwriter_cap: usize,
}
impl FlareIoOptions {
pub fn new() -> Self {
Self {
mode: LogMode::default(),
bufwriter_cap: 0,
filename: String::new(),
}
}
pub fn mode(mut self, mode: LogMode) -> Self {
self.mode = mode;
self
}
pub fn bufwriter_cap(mut self, bufwriter_cap: usize) -> Self {
self.bufwriter_cap = bufwriter_cap;
self
}
pub fn filename(mut self, filename: String) -> Self {
self.filename = filename;
self
}
}
#[derive(Clone)]
pub struct FlareIoWorkerInterface {
pub receiver: SerializedReceiver,
}
impl FlareIoWorkerInterface {
pub fn new(receiver: SerializedReceiver) -> Self {
Self {
receiver,
}
}
}