use std::{
env, process,
time::{SystemTime, UNIX_EPOCH},
};
use steda::{Error, Result, Steda, Worker};
use tokio::{sync::oneshot, task::JoinHandle};
pub(super) async fn connect() -> Result<Steda> {
let database_url = env::var("DATABASE_URL").map_err(|_| {
Error::Other(
"DATABASE_URL is not set; point it at a PostgreSQL database before running this example"
.to_owned(),
)
})?;
let steda = Steda::connect(&database_url).await?;
sqlx::raw_sql(include_str!("../../sql/steda.sql")).execute(steda.pool()).await?;
Ok(steda)
}
#[allow(
dead_code,
clippy::allow_attributes,
reason = "shared example helper is not used by every example crate"
)]
pub(super) fn unique_key(prefix: &str) -> Result<String> {
let nanos = SystemTime::now()
.duration_since(UNIX_EPOCH)
.map_err(|error| Error::Other(format!("system clock is before UNIX_EPOCH: {error}")))?
.as_nanos();
Ok(format!("{prefix}:{}:{nanos}", process::id()))
}
pub(super) struct RunningWorker {
shutdown: Option<oneshot::Sender<()>>,
task: JoinHandle<Result<()>>,
}
impl RunningWorker {
pub(super) fn start(worker: Worker) -> Self {
let (shutdown, shutdown_rx) = oneshot::channel();
let task = tokio::spawn(async move {
worker
.run_until(async move {
let _ = shutdown_rx.await;
})
.await
});
Self { shutdown: Some(shutdown), task }
}
pub(super) async fn stop(mut self) -> Result<()> {
if let Some(shutdown) = self.shutdown.take() {
let _ = shutdown.send(());
}
self.task
.await
.map_err(|error| Error::Other(format!("worker task failed to join: {error}")))?
}
}