pub struct GrpcBlockReader { /* private fields */ }Expand description
A streaming reader for a single Goosefs block.
Wraps a bidirectional gRPC ReadBlock stream and implements
flow-control via offset_received ACK messages.
Implementations§
Source§impl GrpcBlockReader
impl GrpcBlockReader
Sourcepub async fn open(
worker: &WorkerClient,
block_id: i64,
offset: i64,
length: i64,
chunk_size: i64,
open_ufs_block_options: Option<OpenUfsBlockOptions>,
) -> Result<Self>
pub async fn open( worker: &WorkerClient, block_id: i64, offset: i64, length: i64, chunk_size: i64, open_ufs_block_options: Option<OpenUfsBlockOptions>, ) -> Result<Self>
Open a new streaming reader for the specified block range.
This sends the initial ReadRequest and returns a reader
that yields data chunks via read_chunk().
When reading a block that only exists in UFS (e.g. written with
THROUGH mode), pass Some(OpenUfsBlockOptions { .. }) so the
Worker can locate the data in the underlying storage.
Sourcepub async fn open_sequential(
worker: &WorkerClient,
block_id: i64,
offset: i64,
length: i64,
chunk_size: i64,
open_ufs_block_options: Option<OpenUfsBlockOptions>,
tuning: ReadTuning,
) -> Result<Self>
pub async fn open_sequential( worker: &WorkerClient, block_id: i64, offset: i64, length: i64, chunk_size: i64, open_ufs_block_options: Option<OpenUfsBlockOptions>, tuning: ReadTuning, ) -> Result<Self>
Open a sequential block reader with prefetch + buffered drain + ACK coalescing().
Unlike Self::open, this:
- sends
prefetch_windowon the initial request so the worker keeps(1 + prefetch_window)chunks in flight(); - spawns a background task that drains the tonic stream into a bounded
channel (
buffer_messagesdeep), decoupling network pull from application consumption(); - coalesces flow-control ACKs to one per
ack_interval_bytes/ack_interval_chunks(plus a forced ACK at EOF), cutting round-trips . Default is one ACK per chunk (ack_interval_*⇒ every chunk) which is deadlock-safe regardless of the worker’s flow-control window; thetry_sendpath still removes the blocking ACK cost. Coalescing (>1 chunk) is opt-in viaGoosefsConfigfor workers confirmed to honourprefetch_window.
Sourcepub async fn read_chunk(&mut self) -> Result<Option<Bytes>>
pub async fn read_chunk(&mut self) -> Result<Option<Bytes>>
Read the next data chunk from the stream.
Returns None when all expected data has been received.
Sends a flow-control offset_received ACK after each chunk (Direct)
or once per coalescing window (Buffered).
Sourcepub async fn read_all(&mut self) -> Result<Bytes>
pub async fn read_all(&mut self) -> Result<Bytes>
Read all remaining data from this block and return it as a single Bytes.
§H2 short-read guarantee
read_all is the positioned-read tail (used by
Self::positioned_read). The caller has constrained length to a
range it knows is in-file, so a server-side half-close before
bytes_received == length indicates either a truncated stream or a
worker bug — surfacing it as Error::Internal lets the upper layer
(GoosefsFileInStream::read_at) decide whether to retry or propagate,
instead of returning misaligned data via a silent short read.
The streaming sequential path uses Self::read_chunk directly and
is unaffected by this check.
Sourcepub fn bytes_received(&self) -> i64
pub fn bytes_received(&self) -> i64
Total bytes received so far.
Sourcepub fn is_complete(&self) -> bool
pub fn is_complete(&self) -> bool
Whether all expected data has been received.
Sourcepub async fn positioned_read(
worker: &WorkerClient,
block_id: i64,
offset: i64,
length: i64,
chunk_size: i64,
open_ufs_block_options: Option<OpenUfsBlockOptions>,
) -> Result<Bytes>
pub async fn positioned_read( worker: &WorkerClient, block_id: i64, offset: i64, length: i64, chunk_size: i64, open_ufs_block_options: Option<OpenUfsBlockOptions>, ) -> Result<Bytes>
Perform a one-shot positioned read from offset for length bytes.
Opens a new gRPC stream with position_short = true, reads all
data, and returns it as a single Bytes. The new stream is discarded
after this call.
§Design
position_short = true instructs the worker to:
- Skip prefetch / eviction — serve the range directly from cache or UFS.
- Complete the stream after delivering exactly
lengthbytes.
This path is chosen by GoosefsFileInStream when the caller uses
read_at() (random access) or when the seek distance exceeds the
TRANSFER_POSITIONED_READ_THRESHOLD (8 KiB).
§Arguments
worker— connectedWorkerClient.block_id— block to read from.offset— byte offset within the block.length— number of bytes to read.chunk_size— preferred gRPC chunk size.open_ufs_block_options— required for THROUGH-mode blocks.
Trait Implementations§
Source§impl Drop for GrpcBlockReader
impl Drop for GrpcBlockReader
Auto Trait Implementations§
impl !RefUnwindSafe for GrpcBlockReader
impl !UnwindSafe for GrpcBlockReader
impl Freeze for GrpcBlockReader
impl Send for GrpcBlockReader
impl Sync for GrpcBlockReader
impl Unpin for GrpcBlockReader
impl UnsafeUnpin for GrpcBlockReader
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoRequest<T> for T
impl<T> IntoRequest<T> for T
Source§fn into_request(self) -> Request<T>
fn into_request(self) -> Request<T>
T in a tonic::Request