use saddle_observability::{EarlyRequestContext, FrameworkRequestFailure, RequestDiagnosticScope};
use saddle_runtime::request_task::{
admitted_request_task, rejection_request_task, RequestTaskJoin,
};
use std::collections::HashMap;
fn early() -> RequestDiagnosticScope<'static> {
RequestDiagnosticScope::early(None, EarlyRequestContext::socket_accepted("configured-app"))
}
#[allow(dead_code)]
async fn admitted(owner: saddle_runtime::profusegw::ProfuseGwManagedDispatch) {
let (future, ticket) = admitted_request_task(owner, early(), None, |owner, _context| {
Box::pin(async move {
let _ = owner.deadline_unix_ms();
Ok::<_, FrameworkRequestFailure<std::io::Error>>(())
})
});
let mut tasks = tokio::task::JoinSet::new();
let abort = tasks.spawn(future);
let ticket = ticket.bind_spawned(abort.id()).ok().unwrap();
let (owner, outcome) = ticket
.complete(tasks.join_next().await.unwrap())
.ok()
.unwrap();
let terminal = outcome.finish();
assert!(terminal.outcome().result().unwrap().is_ok());
drop(terminal);
owner.cancel();
}
async fn run() {
const MAX_REJECTION_WRITES: usize = 16;
let mut tasks = tokio::task::JoinSet::new();
let mut tickets: HashMap<tokio::task::Id, RequestTaskJoin> = HashMap::new();
assert!(tasks.len() < MAX_REJECTION_WRITES);
let (future, ticket) = rejection_request_task(early(), None, |context| async move {
Err::<(), _>(context.scope().fail(
std::io::Error::from(std::io::ErrorKind::UnexpectedEof),
saddle_core::DiagnosticCategory::UnexpectedError,
saddle_core::BoundedDiagnosticCause::new(
saddle_core::DiagnosticStage::BackgroundTask,
saddle_core::DiagnosticCode::new("example.request_task_read").unwrap(),
),
))
});
let abort = tasks.spawn(future);
tickets.insert(abort.id(), ticket.bind_spawned(abort.id()).ok().unwrap());
while let Some(result) = tasks.join_next_with_id().await {
let (id, result) = match result {
Ok((id, result)) => (id, Ok(result)),
Err(error) => (error.id(), Err(error)),
};
let terminal = tickets
.remove(&id)
.unwrap()
.complete(result)
.ok()
.unwrap()
.finish();
let failure = terminal.outcome().result().unwrap().as_ref().err().unwrap();
assert_eq!(failure.error().kind(), std::io::ErrorKind::UnexpectedEof);
assert_eq!(
failure.submission(),
saddle_observability::DiagnosticSubmission::OutputUnavailable
);
}
assert!(tickets.is_empty());
}
fn main() {
tokio::runtime::Builder::new_current_thread()
.enable_all()
.build()
.unwrap()
.block_on(run());
}