pub struct MasterClient { /* private fields */ }Expand description
Client for Goosefs FileSystemMasterClientService (Master:9200).
In HA mode, the client holds a reference to the MasterInquireClient
and can automatically re-discover the Primary Master when RPCs fail.
§Authentication
The client supports NOSASL and SIMPLE authentication modes.
When config.auth_type is Simple, the client performs a SASL PLAIN
handshake after establishing the gRPC channel, then injects a channel-id
metadata header into all subsequent RPCs.
§Concurrency model
state is an ArcSwap holding the immutable
(channel + sasl_guard) pair. The RPC hot path uses
state.load() — a wait-free single atomic load — to obtain a snapshot,
then clones the lightweight AuthenticatedFsClient (which is itself an
Arc-shared tonic Channel). Failover (reconnect) atomically
publishes a new snapshot via state.store(...); readers either see the
old snapshot (still valid for in-flight requests) or the new one — never
a torn mix.
The hot-path counters (counter_*) are cached as Arc<Counter> here
outside of AuthedState on purpose: they are process-level metric
handles that must outlive any reconnect and must not be re-resolved
from the global DashMap on every RPC. See
rule.
Implementations§
Source§impl MasterClient
impl MasterClient
Sourcepub async fn connect(config: &GoosefsConfig) -> Result<Self>
pub async fn connect(config: &GoosefsConfig) -> Result<Self>
Connect to the Goosefs Master.
In single-master mode, connects directly to config.master_addr.
In HA mode (multiple addresses in config.master_addrs), uses
PollingMasterInquireClient
to discover the Primary first.
Authentication is performed according to config.auth_type.
Sourcepub async fn connect_with_inquire(
config: &GoosefsConfig,
inquire_client: Arc<dyn MasterInquireClient>,
) -> Result<Self>
pub async fn connect_with_inquire( config: &GoosefsConfig, inquire_client: Arc<dyn MasterInquireClient>, ) -> Result<Self>
Connect using an externally-provided MasterInquireClient.
This is useful when sharing a single inquire client across multiple
client types (e.g. MasterClient + WorkerManagerClient).
Sourcepub fn from_channel(channel: Channel, config: GoosefsConfig) -> Self
pub fn from_channel(channel: Channel, config: GoosefsConfig) -> Self
Create from an existing tonic channel (useful for testing / channel sharing).
Note: This bypasses authentication. The channel is wrapped with a no-op channel-id interceptor for API compatibility.
Sourcepub async fn get_status(&self, path: &str) -> Result<FileInfo>
pub async fn get_status(&self, path: &str) -> Result<FileInfo>
Get the file/directory status (equivalent to stat / head).
Sends Java FileSystemOptions.getStatusDefaults:
loadMetadataType from GoosefsConfig::file_metadata_load_type
(default ONCE) and syncIntervalMs from
GoosefsConfig::file_metadata_sync_interval (default -1).
The Master handler uses client options as-is (GetStatusContext.create,
no server-side merge). An unset loadMetadataType is proto enum 0
(NEVER), so COS/UFS files not yet in the namespace would return
NotFound. Matching Java is required for OpenDAL stat.
Sourcepub async fn get_status_with_load_type(
&self,
path: &str,
load_metadata_type: Option<LoadMetadataPType>,
sync_interval_ms: Option<i64>,
) -> Result<FileInfo>
pub async fn get_status_with_load_type( &self, path: &str, load_metadata_type: Option<LoadMetadataPType>, sync_interval_ms: Option<i64>, ) -> Result<FileInfo>
GetStatus with an explicit load_metadata_type / sync_interval_ms.
§Java authority
The close() recovery path in GoosefsFileOutStream re-reads the file
with LoadMetadataPType.ALWAYS and syncIntervalMs = 0 after a
completeFile failure, forcing the Master to re-import metadata from
the UFS copy that was already written.
Unlike Self::get_status this deliberately bypasses no client-side
cache of its own — callers wanting cache semantics should go through
FileSystem::get_status_with_options.
Sourcepub async fn list_status(
&self,
path: &str,
recursive: bool,
) -> Result<Vec<FileInfo>>
pub async fn list_status( &self, path: &str, recursive: bool, ) -> Result<Vec<FileInfo>>
List the contents of a directory. Returns all FileInfo entries.
GooseFS 2.0 dropped ListStatusPOptions.recursive; each Master RPC
returns a single directory level. When recursive is true, this
method walks descendants client-side (BFS), matching Java
BaseFileSystem.iterateStatusInternal and the historical SDK contract
that list_status(path, true) returns the full subtree.
Every level — recursive or not — sends Java
FileSystemOptions.listStatusDefaults: loadMetadataType from
GoosefsConfig::file_metadata_load_type (default ONCE) and
syncIntervalMs from GoosefsConfig::file_metadata_sync_interval
(default -1). Callers that need Never / Always should use
Self::list_status_with_load_type. The BFS skips a child whose path
is the directory currently being listed (/foo and /foo/ are the
same node), so a server that echoes self cannot loop forever.
Each level wraps a server-side streaming RPC — the server sends
multiple ListStatusPResponse messages, each containing a batch
of FileInfo.
Sourcepub async fn list_status_with_load_type(
&self,
path: &str,
recursive: bool,
load_metadata_type: Option<LoadMetadataPType>,
) -> Result<Vec<FileInfo>>
pub async fn list_status_with_load_type( &self, path: &str, recursive: bool, load_metadata_type: Option<LoadMetadataPType>, ) -> Result<Vec<FileInfo>>
List a directory, applying load_metadata_type on every Master RPC.
None resolves to GoosefsConfig::file_metadata_load_type (default
ONCE), and syncIntervalMs comes from the config — same as
Self::list_status.
Sourcepub async fn list_status_with_options(
&self,
path: &str,
recursive: bool,
load_metadata_type: Option<LoadMetadataPType>,
sync_interval_ms: Option<i64>,
) -> Result<Vec<FileInfo>>
pub async fn list_status_with_options( &self, path: &str, recursive: bool, load_metadata_type: Option<LoadMetadataPType>, sync_interval_ms: Option<i64>, ) -> Result<Vec<FileInfo>>
ListStatus with an explicit load_metadata_type / sync_interval_ms.
Mirrors Self::get_status_with_load_type so that a FileSystem
layer which resolved both values from ListStatusOptions can pass
them straight through.
Sourcepub async fn create_file(
&self,
path: &str,
options: CreateFilePOptions,
) -> Result<FileInfo>
pub async fn create_file( &self, path: &str, options: CreateFilePOptions, ) -> Result<FileInfo>
Create a new file. Returns the FileInfo of the created file.
Sourcepub async fn complete_file(
&self,
path: &str,
ufs_length: Option<i64>,
operation_id: Option<FsOpPId>,
) -> Result<()>
pub async fn complete_file( &self, path: &str, ufs_length: Option<i64>, operation_id: Option<FsOpPId>, ) -> Result<()>
Mark a file as completed (called after all blocks are written).
§Idempotent operation ID
operation_id is used by the Master for exactly-once semantics: if the
RPC is retried after a network hiccup the Master detects the duplicate
via FsOpPId and returns success without applying the operation twice.
The caller (GoosefsFileWriter) generates a fresh uuid::Uuid at
construction time and reuses it across all complete_file calls for the
same write session. The UUID is split into two i64 halves via
Uuid::as_u64_pair():
(high, low) = uuid.as_u64_pair()
FsOpPId { most_significant_bits: high as i64,
least_significant_bits: low as i64 }This matches Java UUID.getMostSignificantBits() / getLeastSignificantBits()
as verified in DefaultFileSystemMaster.completeFile().
§Note on Go SDK bug
The Go SDK base_filesystem.go:394-400 accepts an operationID parameter
but never writes it to the proto request. The Rust implementation
fixes this: operation_id is always wired into CompleteFilePOptions.
Sourcepub async fn complete_file_with_options(
&self,
path: &str,
opts: CompleteFileOptions,
) -> Result<()>
pub async fn complete_file_with_options( &self, path: &str, opts: CompleteFileOptions, ) -> Result<()>
CompleteFile with ASYNC_THROUGH location metadata and persist options.
§Java authority
Matches GoosefsFileOutStream.close() which puts the last block’s
writeSucceedWorkers into CompleteFilePOptions.locations and, for
ASYNC_THROUGH, embeds asyncPersistOptions rather than issuing a
separate ScheduleAsyncPersistence RPC.
Sourcepub async fn commit_location(
&self,
path: &str,
inode_id: Option<i64>,
block_id: i64,
locations: Vec<FileLocation>,
) -> Result<()>
pub async fn commit_location( &self, path: &str, inode_id: Option<i64>, block_id: i64, locations: Vec<FileLocation>, ) -> Result<()>
Commit a completed block’s replica locations to Master.
§Java authority
Matches GoosefsFileOutStream.commitCurrentBlock() →
FileSystemMasterClient.commitLocation. Called after every block
except the last (the last block’s locations travel with completeFile).
Sourcepub async fn remove_blocks(&self, block_ids: Vec<i64>) -> Result<()>
pub async fn remove_blocks(&self, block_ids: Vec<i64>) -> Result<()>
Request the Master to free block metadata for the given block IDs.
This is the preferred cleanup path for GoosefsFileWriter::cancel():
it removes only the block metadata on the Master without touching the
file-system namespace entry (the INCOMPLETE inode).
Falls back to delete_with_options(unchecked=true) when this RPC fails.
§Java authority
Matches FileSystemMasterClientServiceHandler.removeBlocks() →
DefaultFileSystemMaster.removeBlocks(blockIds).
Sourcepub async fn delete_with_options(
&self,
path: &str,
opts: DeleteOptions,
) -> Result<()>
pub async fn delete_with_options( &self, path: &str, opts: DeleteOptions, ) -> Result<()>
Delete a file or directory with fine-grained options.
Prefer this over the legacy delete wrapper when you need
unchecked or goosefs_only semantics.
See DeleteOptions for field semantics and Java authority notes.
Sourcepub async fn delete(&self, path: &str, recursive: bool) -> Result<()>
pub async fn delete(&self, path: &str, recursive: bool) -> Result<()>
Delete a file or directory (simple recursive wrapper).
For unchecked or goosefs_only deletion use delete_with_options
directly.
Sourcepub async fn rename(&self, src: &str, dst: &str) -> Result<()>
pub async fn rename(&self, src: &str, dst: &str) -> Result<()>
Rename (move) a file or directory.
Sourcepub async fn create_directory(&self, path: &str, recursive: bool) -> Result<()>
pub async fn create_directory(&self, path: &str, recursive: bool) -> Result<()>
Create a directory (recursive by default).
Sets a default mode of 0755 (rwxr-xr-x) so that the corresponding
UFS directory created by Goosefs has usable permissions.
Sourcepub async fn schedule_async_persistence(
&self,
path: &str,
persistence_wait_time: Option<i64>,
) -> Result<()>
pub async fn schedule_async_persistence( &self, path: &str, persistence_wait_time: Option<i64>, ) -> Result<()>
Schedule asynchronous persistence for a file. This will persist the file to the underlying storage system.
Sourcepub fn config(&self) -> &GoosefsConfig
pub fn config(&self) -> &GoosefsConfig
Get a reference to the underlying config.
Sourcepub fn inquire_client(&self) -> &Arc<dyn MasterInquireClient> ⓘ
pub fn inquire_client(&self) -> &Arc<dyn MasterInquireClient> ⓘ
Get a reference to the underlying inquire client.
Useful for sharing the same inquire client with WorkerManagerClient.
Trait Implementations§
Source§impl Clone for MasterClient
impl Clone for MasterClient
Source§fn clone(&self) -> MasterClient
fn clone(&self) -> MasterClient
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 !RefUnwindSafe for MasterClient
impl !UnwindSafe for MasterClient
impl Freeze for MasterClient
impl Send for MasterClient
impl Sync for MasterClient
impl Unpin for MasterClient
impl UnsafeUnpin for MasterClient
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