twizzler_driver/request/mod.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
//! A system for handling requests and organizing inflight requests while waiting for responses.
//!
//! The general structure of this system is that software implements the [RequestDriver] trait with
//! some struct that we'll call "the request driver" or just "the driver". The driver is then
//! wrapped by a [Requester], which internally manages the asynchrony of talking to devices.
//!
//! A user of the requester can call the [Requester::submit] or [Requester::submit_for_response]
//! functions to submit a set a requests depending on if the caller wants the responses or just
//! wants to know if the requests succeeded. The reason this distinction is maintained is that
//! collecting responses has an overhead. The requester interacts with the driver to submit the
//! requests.
//!
//! Internally, the requester assigns IDs to requests for use in communicating with the driver.
//! These IDs are not necessarily allocated sequentially and can only be relied upon to be unique
//! while a given request is inflight.
//!
//! Once a request is completed by the driver, the driver should send the response data and ID of
//! the request that completed back to the requester with the [Requester::finish] function. The
//! request manager will then collate the responses for matching with the requests and any errors
//! are tracked. Once all requests in a submitted set have been completed, that set of requests is
//! finished and awaiting on it will return a [SubmitSummary] or a [SubmitSummaryWithResponses].
mod async_ids;
mod inflight;
mod requester;
mod response_info;
mod submit;
mod summary;
#[async_trait::async_trait]
/// A trait implemented by a particular driver that can the be used by a [requester::Requester].
pub trait RequestDriver {
/// The type of a request that will be used by the SubmitRequest wrapper to submit requests to
/// the driver.
type Request: Copy + Send;
/// The type of a response to a request that we will use to send back to the Requester via the
/// [requester::Requester::finish] function.
type Response: Copy + Send;
/// The type of a submit error in case submission fails.
type SubmitError;
/// The actual submit function. The driver should perform whatever device-specific submission
/// procedure it needs to to submit all requests.
async fn submit(
&self,
reqs: &mut [SubmitRequest<Self::Request>],
) -> Result<(), Self::SubmitError>;
/// Manually flush any internal driver submission queue.
fn flush(&self);
/// The number of IDs to have in-flight at a time.
const NUM_IDS: usize;
}
// TODO: drop for inflight tracker, so we can remove it to save work?
pub use inflight::{InFlightFuture, InFlightFutureWithResponses};
pub use requester::Requester;
pub use response_info::ResponseInfo;
pub use submit::SubmitRequest;
pub use summary::{SubmitSummary, SubmitSummaryWithResponses};