use std::thread::{self, JoinHandle};
use crate::ServerError;
#[derive(Debug)]
pub struct ReclaimRelease {
worker: Option<JoinHandle<()>>,
failure: Option<String>,
}
impl ReclaimRelease {
pub(crate) fn start(work: impl FnOnce() + Send + 'static) -> Result<Self, ServerError> {
let worker = thread::Builder::new()
.name(super::RELEASE_THREAD.to_owned())
.spawn(work)
.map_err(|error| refusal(format!("spine reclaim release could not start: {error}")))?;
Ok(Self {
worker: Some(worker),
failure: None,
})
}
pub(crate) fn finish(&mut self) -> Result<(), ServerError> {
if let Some(failure) = &self.failure {
return Err(refusal(failure.clone()));
}
if let Some(worker) = self.worker.take()
&& worker.join().is_err()
{
let message = "spine reclaim release panicked during shutdown";
self.failure = Some(message.to_owned());
return Err(refusal(message));
}
Ok(())
}
}
impl Drop for ReclaimRelease {
fn drop(&mut self) {
if let Err(error) = self.finish() {
tracing::error!(%error, "spine reclaim release teardown failed");
}
}
}
fn refusal(message: impl Into<String>) -> ServerError {
ServerError::ListenerAccept {
message: message.into(),
}
}