use crate::capacity::{Held, Pool, Refusal, Reservation};
use crate::manager::ENTRY_OVERHEAD;
use crate::{MemorySize, ReadBatch, Result, StorageManager};
pub struct ReadSession<C = ()> {
pub(crate) manager: StorageManager<C>,
pub(crate) held: Held,
pub(crate) queued: bool,
}
impl<C> Clone for ReadSession<C> {
fn clone(&self) -> Self {
Self { manager: self.manager.clone(), held: self.held.clone(), queued: self.queued }
}
}
impl<C> StorageManager<C> {
#[tracing::instrument(name = "storage.read_session.new", level = "trace", skip_all)]
pub fn read_session(&self) -> ReadSession<C> {
ReadSession { manager: self.clone(), held: Held::default(), queued: false }
}
}
impl<C> ReadSession<C> {
pub(crate) fn standalone(manager: &StorageManager<C>) -> Self {
Self { manager: manager.clone(), held: Held::default(), queued: true }
}
#[tracing::instrument(name = "storage.read_session.try_memory", level = "trace", skip_all, fields(bytes = payload_bytes.get(), outcome = "cancelled"))]
pub fn try_memory(&self, payload_bytes: std::num::NonZeroUsize) -> Result<crate::arrow::RetainedMemory> {
let result: Result<crate::arrow::RetainedMemory> = (|| {
let total = payload_bytes
.get()
.checked_add(ENTRY_OVERHEAD)
.ok_or(crate::Error::ResourceExhausted { resource: "session read memory" })?;
Reservation::try_new(&self.manager.inner, Pool::Read, &self.held, total).map(Reservation::retain).map_err(Refusal::into_error)
})();
tracing::Span::current().record("outcome", if result.is_ok() { "completed" } else { "failed" });
result
}
#[tracing::instrument(name = "storage.read_session.read_file", level = "trace", skip_all, fields(outcome = "cancelled"))]
pub async fn read_file(&self, request: harmos_domain::operations::storage::ReadFile) -> Result<crate::FileReader> {
let result = self.manager.read_file_with_held(request, self.held.clone()).await;
tracing::Span::current().record("outcome", if result.is_ok() { "completed" } else { "failed" });
result
}
#[tracing::instrument(name = "storage.read_session.collection", level = "trace", skip_all, fields(outcome = "cancelled"))]
pub fn collection<U: MemorySize>(&self) -> Result<ReadBatch<Vec<ReadBatch<U>>>> {
let result: Result<ReadBatch<Vec<ReadBatch<U>>>> = (|| {
let reservation =
Reservation::try_new(&self.manager.inner, Pool::Read, &self.held, ENTRY_OVERHEAD).map_err(Refusal::into_error)?;
Ok(ReadBatch::new(Vec::new(), reservation))
})();
tracing::Span::current().record("outcome", if result.is_ok() { "completed" } else { "failed" });
result
}
}