pub struct WorkerClient { /* private fields */ }Expand description
Client for BlockWorker service on a single worker node.
Each WorkerClient carries a monotonic generation tag assigned by
WorkerClientPool at construction time. The generation allows callers
that observed a failure on a specific client to request a single-flight
reconnect via WorkerClientPool::reconnect_if_stale: only the first
observer of generation N actually re-establishes the TCP+SASL
connection; all concurrent observers with the same (or older) generation
simply receive the already-replaced client. This collapses the
“thundering-herd reconnect” that previously produced hundreds of duplicate
authentication failed warnings when a SASL session expired.
Implementations§
Source§impl WorkerClient
impl WorkerClient
Sourcepub async fn connect(addr: &str, config: &GoosefsConfig) -> Result<Self>
pub async fn connect(addr: &str, config: &GoosefsConfig) -> Result<Self>
Connect to a Goosefs Worker at the given address with authentication.
Authentication is performed according to config.auth_type.
Sourcepub async fn connect_simple(
addr: &str,
connect_timeout: Duration,
) -> Result<Self>
pub async fn connect_simple( addr: &str, connect_timeout: Duration, ) -> Result<Self>
Connect to a Goosefs Worker with only connect_timeout (backward compatible, NOSASL).
Deprecated: Use connect(addr, config) instead for proper authentication.
Sourcepub fn from_channel(channel: Channel, addr: String) -> Self
pub fn from_channel(channel: Channel, addr: String) -> Self
Create from an existing tonic channel (useful for testing / channel sharing).
Note: This bypasses authentication.
Sourcepub async fn read_block(
&self,
block_id: i64,
offset: i64,
length: i64,
chunk_size: i64,
prefetch_window: Option<i32>,
open_ufs_block_options: Option<OpenUfsBlockOptions>,
) -> Result<(Sender<ReadRequest>, Streaming<ReadResponse>)>
pub async fn read_block( &self, block_id: i64, offset: i64, length: i64, chunk_size: i64, prefetch_window: Option<i32>, open_ufs_block_options: Option<OpenUfsBlockOptions>, ) -> Result<(Sender<ReadRequest>, Streaming<ReadResponse>)>
Start a bidirectional streaming ReadBlock RPC.
Returns: (request_sender, response_stream)
The caller sends an initial ReadRequest with block_id/offset/length,
then sends periodic offset_received ACKs. The response stream yields
ReadResponse containing Chunk data.
When the block is only stored in UFS (e.g. written with THROUGH mode),
open_ufs_block_options must be provided so the Worker knows how to
locate and read the data from the underlying storage.
Sourcepub async fn read_block_positioned(
&self,
block_id: i64,
offset: i64,
length: i64,
chunk_size: i64,
open_ufs_block_options: Option<OpenUfsBlockOptions>,
) -> Result<(Sender<ReadRequest>, Streaming<ReadResponse>)>
pub async fn read_block_positioned( &self, block_id: i64, offset: i64, length: i64, chunk_size: i64, open_ufs_block_options: Option<OpenUfsBlockOptions>, ) -> Result<(Sender<ReadRequest>, Streaming<ReadResponse>)>
Open a positioned (random-access) block read stream.
Identical to read_block but sets position_short = true in the
initial ReadRequest, instructing the worker to skip prefetch and
serve the exact requested byte range.
Used by crate::io::reader::GrpcBlockReader::positioned_read.
Sourcepub async fn check_blocks(&self, block_ids: &[i64]) -> Result<HashMap<i64, i64>>
pub async fn check_blocks(&self, block_ids: &[i64]) -> Result<HashMap<i64, i64>>
Probe this worker for cached bytes of block_ids in the local store.
Mirrors Java 2.0 BlockWorkerClient.checkBlocks /
CheckBlocksResponse.block_cached_bytes. Returns block_id → cached_bytes.
On GooseFS 2.1.0 workers the same field carries bool-as-0/1; treat
cached_bytes > 0 as present.
Sourcepub async fn write_block(
&self,
block_id: i64,
space_to_reserve: i64,
options: WriteBlockOptions,
) -> Result<WriteBlockHandle>
pub async fn write_block( &self, block_id: i64, space_to_reserve: i64, options: WriteBlockOptions, ) -> Result<WriteBlockHandle>
Start a bidirectional streaming WriteBlock RPC.
Returns a WriteBlockHandle that manages the background gRPC task.
The caller sends data chunks through handle.request_tx, then calls
handle.recv_response() to get flush acknowledgements.
§Why a background task?
Goosefs Worker’s WriteBlock RPC does not send HTTP/2 response
headers until the client sends a flush command or closes the stream.
tonic’s client.write_block(stream).await waits for response headers
before resolving, so calling it inline would deadlock — we’d need the
returned sender to send flush, but we can’t get the sender until the
call resolves.
By spawning the gRPC call in a background task and forwarding responses through an mpsc channel, we decouple request sending from response receiving.
Sourcepub fn generation(&self) -> u64
pub fn generation(&self) -> u64
The monotonic generation tag assigned by the pool.
Callers should save this value alongside the WorkerClient when
starting an RPC; if the RPC fails with an authentication error they
pass the saved generation back to
WorkerClientPool::reconnect_if_stale to trigger a single-flight
reconnect (de-duplicating concurrent observers of the same failure).
Trait Implementations§
Source§impl Clone for WorkerClient
impl Clone for WorkerClient
Source§fn clone(&self) -> WorkerClient
fn clone(&self) -> WorkerClient
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreAuto Trait Implementations§
impl !Freeze for WorkerClient
impl !RefUnwindSafe for WorkerClient
impl !UnwindSafe for WorkerClient
impl Send for WorkerClient
impl Sync for WorkerClient
impl Unpin for WorkerClient
impl UnsafeUnpin for WorkerClient
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> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
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