You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
39 lines
1.1 KiB
39 lines
1.1 KiB
use crate::UError; |
|
use anyhow::Error; |
|
use once_cell::sync::OnceCell; |
|
use tokio::sync::mpsc::{channel, error::TryRecvError, Receiver, Sender}; |
|
use tokio::sync::{Mutex, MutexGuard}; |
|
|
|
type ChanError = Error; |
|
static ERR_CHAN: OnceCell<Mutex<ErrChan>> = OnceCell::new(); |
|
|
|
pub struct ErrChan { |
|
tx: Sender<ChanError>, |
|
rx: Receiver<ChanError>, |
|
} |
|
|
|
impl ErrChan { |
|
async fn get() -> MutexGuard<'static, Self> { |
|
ERR_CHAN |
|
.get_or_init(|| { |
|
let (tx, rx) = channel(20); |
|
Mutex::new(Self { tx, rx }) |
|
}) |
|
.lock() |
|
.await |
|
} |
|
|
|
pub async fn send(err: impl Into<ChanError>, ctx: impl AsRef<str>) { |
|
let err = err.into(); |
|
error!("Encountered an error at '{}': {:?}", ctx.as_ref(), err); |
|
Self::get().await.tx.try_send(err).unwrap(); |
|
} |
|
|
|
pub async fn recv() -> Option<UError> { |
|
match Self::get().await.rx.try_recv() { |
|
Ok(err) => Some(UError::from(err)), |
|
Err(TryRecvError::Disconnected) => panic!("err chan disconnected"), |
|
Err(TryRecvError::Empty) => None, |
|
} |
|
} |
|
}
|
|
|