use std::sync::atomic::Ordering;
use crate::base_types::TgqeCtx;
use crate::channel::renderer::Renderer;
use crate::singletons::{
Configure, ERROR_COUNTER,
};
#[cfg(feature = "store-to-db")]
use crate::singletons::DBManager;
pub struct TgqeBus {
mailbox: Vec<TgqeCtx>,
}
impl TgqeBus {
pub(crate) fn new() -> Self {
Self {
mailbox: Vec::new(),
}
}
pub async fn report(
&mut self,
ctxs: &mut Vec<TgqeCtx>,
) {
self.mailbox.append(ctxs);
self.auto_report().await;
}
async fn auto_report(&mut self) {
let errors = std::mem::take(
&mut self.mailbox,
);
let mut render_count = 0usize;
for (i, ctx) in
errors.iter().enumerate()
{
ERROR_COUNTER.fetch_add(
1,
Ordering::Relaxed,
);
if ERROR_COUNTER
.load(Ordering::Relaxed)
> Configure.render_limit
{
break;
}
Renderer::draw(ctx);
render_count = i + 1;
}
let rest = errors
.into_iter()
.skip(render_count);
#[cfg(feature = "store-to-db")]
{
let rest: Vec<TgqeCtx> =
rest.collect();
if !rest.is_empty() {
self.save(rest).await;
}
}
#[cfg(not(feature = "store-to-db"))]
for ctx in rest {
ERROR_COUNTER.fetch_add(
1,
Ordering::Relaxed,
);
Renderer::draw(&ctx);
}
}
#[cfg(feature = "store-to-db")]
async fn save(
&self,
errors: Vec<TgqeCtx>,
) {
let mut db =
DBManager.lock().unwrap();
if let Err(e) =
db.batch_save(&errors).await
{
eprintln!(
"[TGQE] Failed to store to the database: {e}"
);
}
ERROR_COUNTER.fetch_add(
errors.len() as u64,
Ordering::Relaxed,
);
}
}