Struct GooseFs
pub struct GooseFs { /* private fields */ }services-goosefs only.Expand description
GooseFS services support via native gRPC.
§Capabilities
This service can be used to:
- create_dir
- stat
- read
- write
- delete
- list
- copy
- rename
- presign
§Notes
GooseFS service uses native gRPC protocol (not REST API like Alluxio), which means it connects directly to GooseFS Master (port 9200) and Worker (port 9203) without requiring a Proxy component.
Features:
- HA support: Comma-separated master addresses for automatic Primary Master discovery.
- Block-level I/O: Data reads/writes go through block-level gRPC bidirectional streaming.
- Consistent hash routing: Worker selection uses consistent hashing on block IDs.
- All WriteTypes: Supports MUST_CACHE, CACHE_THROUGH, THROUGH, and ASYNC_THROUGH.
§Configuration
root: Set the work directory for backendmaster_addr: GooseFS Master address (host:port), supports comma-separated for HAblock_size: Block size for new files (default: 64 MiB)chunk_size: Chunk size for streaming RPCs (default: 1 MiB)write_type: Default write type (must_cache,cache_through,through,async_through)auth_type: Authentication type (nosasl,simple). Default:simpleauth_username: Authentication username for SIMPLE mode. Default: current OS user
You can refer to GoosefsBuilder’s docs for more information
§Example
§Via Builder
use opendal::Operator;
use opendal::Result;
use opendal::services::GooseFs;
#[tokio::main]
async fn main() -> Result<()> {
// Single master
let builder = GooseFs::default()
.root("/data")
.master_addr("10.0.0.1:9200");
let op: Operator = Operator::new(builder)?.finish();
Ok(())
}§Via URI
use opendal::Operator;
use opendal::Result;
#[tokio::main]
async fn main() -> Result<()> {
let op = Operator::from_uri("goosefs://10.0.0.1:9200/data")?;
Ok(())
}§HA Mode
use opendal::Operator;
use opendal::Result;
use opendal::services::GooseFs;
#[tokio::main]
async fn main() -> Result<()> {
let builder = GooseFs::default()
.root("/data")
.master_addr("10.0.0.1:9200,10.0.0.2:9200,10.0.0.3:9200")
.write_type("cache_through");
let op: Operator = Operator::new(builder)?.finish();
Ok(())
}§With Authentication
use opendal::Operator;
use opendal::Result;
use opendal::services::GooseFs;
#[tokio::main]
async fn main() -> Result<()> {
// SIMPLE authentication (default) with custom username
let builder = GooseFs::default()
.root("/data")
.master_addr("10.0.0.1:9200")
.auth_type("simple")
.auth_username("myuser");
let op: Operator = Operator::new(builder)?.finish();
// No authentication (NOSASL mode)
let builder = GooseFs::default()
.root("/data")
.master_addr("10.0.0.1:9200")
.auth_type("nosasl");
let op: Operator = Operator::new(builder)?.finish();
Ok(())
}§Testing
This service is covered by all three OpenDAL test layers:
-
Unit tests (no cluster required) — exercise
Config/Builder/error-mapping boundaries. Run:cargo test -p opendal-service-goosefs -
Behavior tests (require a running GooseFS cluster) — the shared
core/tests/behaviorsuite (read/write/list/stat/rename/delete/create_dir). Start the fixture and point the harness at it:# Start a single-container GooseFS (master + worker + job_master + # job_worker + table_master) docker compose -f fixtures/goosefs/docker-compose-goosefs.yml up -d --wait OPENDAL_TEST=goosefs \ OPENDAL_GOOSEFS_MASTER_ADDR=127.0.0.1:9200 \ OPENDAL_GOOSEFS_ROOT=/ \ cargo test behavior --features tests,services-goosefs docker compose -f fixtures/goosefs/docker-compose-goosefs.yml downIf
OPENDAL_TESTis unset the behavior suite automatically skips, so missing a cluster is safe. -
GitHub CI —
.github/services/goosefs/goosefs/action.ymlis picked up automatically by.github/scripts/test_behavior/plan.py::provided_cases()and runs the fixture + behavior suite on every PR. The fixture image (goosefs.tencentcloudcr.com/goosefs/repo:v2.1.0) is public so no secrets are needed.
The fixture also exposes a distributed compose profile (separate master /
worker / job_master / job_worker containers) for multi-node diagnostics;
opt in via --profile distributed.
Implementations§
§impl GoosefsBuilder
impl GoosefsBuilder
pub fn root(self, root: &str) -> GoosefsBuilder
pub fn root(self, root: &str) -> GoosefsBuilder
Set root of this backend.
All operations will happen under this root.
pub fn master_addr(self, addr: &str) -> GoosefsBuilder
pub fn master_addr(self, addr: &str) -> GoosefsBuilder
Set master address(es).
Single master: "10.0.0.1:9200"
HA (comma-separated): "10.0.0.1:9200,10.0.0.2:9200,10.0.0.3:9200"
When provided here it overrides any address discovered from
goosefs-site.properties or GOOSEFS_MASTER_ADDR. When left unset
the builder falls back to the SDK’s auto-discovery chain
(defaults → properties → env) — see goosefs-sdk
docs/CLIENT_CONFIGURATION.md §1. build() fails with
ConfigInvalid only if no source supplies a master address.
pub fn block_size(self, size: u64) -> GoosefsBuilder
pub fn block_size(self, size: u64) -> GoosefsBuilder
Set block size for new files (bytes).
pub fn chunk_size(self, size: u64) -> GoosefsBuilder
pub fn chunk_size(self, size: u64) -> GoosefsBuilder
Set chunk size for streaming RPCs (bytes).
pub fn write_type(self, wt: &str) -> GoosefsBuilder
pub fn write_type(self, wt: &str) -> GoosefsBuilder
Set default write type.
Values: "must_cache", "cache_through", "through", "async_through"
pub fn auth_type(self, auth_type: &str) -> GoosefsBuilder
pub fn auth_type(self, auth_type: &str) -> GoosefsBuilder
Set authentication type.
Values: "nosasl", "simple" (default: "simple").
"nosasl"— skip SASL authentication entirely."simple"— PLAIN SASL with username (server does not verify password).
pub fn auth_username(self, username: &str) -> GoosefsBuilder
pub fn auth_username(self, username: &str) -> GoosefsBuilder
Set authentication username.
Used in SIMPLE mode as the login identity.
Default: current OS user ($USER / $USERNAME).
Trait Implementations§
§impl Builder for GoosefsBuilder
impl Builder for GoosefsBuilder
§impl Debug for GoosefsBuilder
impl Debug for GoosefsBuilder
§impl Default for GoosefsBuilder
impl Default for GoosefsBuilder
§fn default() -> GoosefsBuilder
fn default() -> GoosefsBuilder
Auto Trait Implementations§
impl Freeze for GoosefsBuilder
impl RefUnwindSafe for GoosefsBuilder
impl Send for GoosefsBuilder
impl Sync for GoosefsBuilder
impl Unpin for GoosefsBuilder
impl UnwindSafe for GoosefsBuilder
Blanket Implementations§
§impl<U> As for U
impl<U> As for U
§fn as_<T>(self) -> Twhere
T: CastFrom<U>,
fn as_<T>(self) -> Twhere
T: CastFrom<U>,
self to type T. The semantics of numeric casting with the as operator are followed, so <T as As>::as_::<U> can be used in the same way as T as U for numeric conversions. Read moreSource§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<T> Conv for T
impl<T> Conv for T
§impl<T> FmtForward for T
impl<T> FmtForward for T
§fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
self to use its Binary implementation when Debug-formatted.§fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
self to use its Display implementation when
Debug-formatted.§fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
self to use its LowerExp implementation when
Debug-formatted.§fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
self to use its LowerHex implementation when
Debug-formatted.§fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
self to use its Octal implementation when Debug-formatted.§fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
self to use its Pointer implementation when
Debug-formatted.§fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
self to use its UpperExp implementation when
Debug-formatted.§fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
self to use its UpperHex implementation when
Debug-formatted.§fn fmt_list(self) -> FmtList<Self>where
&'a Self: for<'a> IntoIterator,
fn fmt_list(self) -> FmtList<Self>where
&'a Self: for<'a> IntoIterator,
§impl<T> FutureExt for T
impl<T> FutureExt for T
§fn with_context(self, otel_cx: Context) -> WithContext<Self>
fn with_context(self, otel_cx: Context) -> WithContext<Self>
§fn with_current_context(self) -> WithContext<Self>
fn with_current_context(self) -> WithContext<Self>
§impl<T> Identity for Twhere
T: ?Sized,
impl<T> Identity for Twhere
T: ?Sized,
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more§impl<T> IntoRequest<T> for T
impl<T> IntoRequest<T> for T
§fn into_request(self) -> Request<T>
fn into_request(self) -> Request<T>
T in a tonic::RequestSource§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::RequestSource§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§impl<L> LayerExt<L> for L
impl<L> LayerExt<L> for L
§fn named_layer<S>(&self, service: S) -> Layered<<L as Layer<S>>::Service, S>where
L: Layer<S>,
fn named_layer<S>(&self, service: S) -> Layered<<L as Layer<S>>::Service, S>where
L: Layer<S>,
Layered].§impl<T> Pipe for Twhere
T: ?Sized,
impl<T> Pipe for Twhere
T: ?Sized,
§fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
§fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read more§fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read more§fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
§fn pipe_borrow_mut<'a, B, R>(
&'a mut self,
func: impl FnOnce(&'a mut B) -> R,
) -> R
fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
§fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
self, then passes self.as_ref() into the pipe function.§fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
self, then passes self.as_mut() into the pipe
function.§fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
self, then passes self.deref() into the pipe function.§impl<T> Pointable for T
impl<T> Pointable for T
§impl<T> PolicyExt for Twhere
T: ?Sized,
impl<T> PolicyExt for Twhere
T: ?Sized,
§impl<T> Scope for T
impl<T> Scope for T
§impl<T> Tap for T
impl<T> Tap for T
§fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
Borrow<B> of a value. Read more§fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
BorrowMut<B> of a value. Read more§fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
AsRef<R> view of a value. Read more§fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
AsMut<R> view of a value. Read more§fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
Deref::Target of a value. Read more§fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
Deref::Target of a value. Read more§fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
.tap() only in debug builds, and is erased in release builds.§fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
.tap_mut() only in debug builds, and is erased in release
builds.§fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
.tap_borrow() only in debug builds, and is erased in release
builds.§fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
.tap_borrow_mut() only in debug builds, and is erased in release
builds.§fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
.tap_ref() only in debug builds, and is erased in release
builds.§fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
.tap_ref_mut() only in debug builds, and is erased in release
builds.§fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
.tap_deref() only in debug builds, and is erased in release
builds.