use crate::error::CredentialProxyError;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::{Mutex as StdMutex, MutexGuard};
use tokio::task::JoinHandle;
use tracing::{debug, error};
pub(super) type RefillTaskResult = Result<(), CredentialProxyError>;
#[derive(Default)]
pub(super) struct RefillTask {
join_handle: StdMutex<Option<JoinHandle<RefillTaskResult>>>,
in_progress: AtomicBool,
}
impl RefillTask {
fn try_set_in_progress(&self) -> bool {
self.in_progress
.compare_exchange(false, true, Ordering::SeqCst, Ordering::SeqCst)
.is_ok()
}
pub(super) fn try_get_new_task_guard(
&self,
) -> Option<MutexGuard<'_, Option<JoinHandle<RefillTaskResult>>>> {
if !self.try_set_in_progress() {
debug!("another task has already started deposit refill request");
return None;
}
#[allow(clippy::expect_used)]
let guard = self.join_handle.lock().expect("mutex got poisoned");
if let Some(existing_handle) = guard.as_ref() {
if !existing_handle.is_finished() {
error!(
"CRITICAL BUG: there was already a deposit refill task spawned that hasn't yet finished"
)
}
}
Some(guard)
}
pub(super) fn take_task_join_handle(&self) -> Option<JoinHandle<RefillTaskResult>> {
#[allow(clippy::expect_used)]
self.join_handle.lock().expect("mutex got poisoned").take()
}
}