Skip to content

feat: Add OpenDAL-backed GooseFS object store support #9133

Description

@XuQianJin-Stars

Problem or motivation

Summary

Vortex currently has OpenDAL-backed object store support for Tencent Cloud COS (cos://) and Alibaba Cloud OSS (oss://) in vortex-cloud, but no support for Tencent Cloud GooseFS — a distributed caching file system that is widely used as a high-performance data layer for analytics workloads on top of on-prem or hybrid-cloud storage.

GooseFS exposes a HDFS-like gRPC API rather than a REST-style S3-compatible API, so it is not natively supported by the object_store crate. Users who store Vortex datasets on GooseFS clusters today have no way to read/write them through vortex.io.read_url(...) / vortex.io.write(...) or through the Registry-based URL resolution.

Use case

Several Vortex users (both in production and on the Lance ecosystem side) deploy datasets against GooseFS to get cache-accelerated reads without paying S3 egress. Without GooseFS support in vortex-cloud, those users either fall back to local caching or duplicate the dataset onto an S3-compatible store — both of which defeat GooseFS's positioning as the primary storage tier.

Concretely, we need:

  • A goosefs:// URL scheme that the Registry can resolve to a usable object_store::ObjectStore.
  • A strongly-typed builder (mirroring CosConfig / OssConfig) so Python callers and the JNI layer can construct a store from explicit configuration.
  • Python bindings equivalent to CosStore so vortex.io.read_url(url, store=goosefs_store) works.

Why now

OpenDAL already ships a stable opendal-service-goosefs backend that wraps the official goosefs-sdk gRPC client. The bridging work is entirely on the Vortex side and is structurally identical to the existing COS/OSS implementations, so this is a low-risk incremental addition rather than a new architectural piece.

Proposed solution

Implementation outline

Mirror the existing cos / oss implementation pattern in vortex-cloud (see vortex-cloud/src/opendal/{cos,oss}.rs):

  1. New opendal feature subgroup goosefs in vortex-cloud/Cargo.toml that pulls in opendal, object_store_opendal, tracing, and opendal/services-goosefs.
  2. New vortex-cloud/src/opendal/goosefs.rs module exposing:
    • GOOSEFS_SCHEME: &str = "goosefs"
    • GoosefsConfig { master_addr, root, block_size, chunk_size, write_type, auth_type, auth_username }
    • make_goosefs_store(config) -> Result<Arc<dyn ObjectStore>, OpenDALStoreError>
    • url_and_properties_to_config(url, properties, env_lookup) with master_addr resolved as: properties["master_addr"] → URL authority (host:port) → GOOSEFS_MASTER_ADDR env var.
  3. Wire goosefs into the existing dispatch in vortex-cloud/src/opendal/mod.rs (SUPPORTED_SCHEMES, make_opendal_store_with_env match arm) and the Registry's OpenDAL cfg gates in vortex-cloud/src/registry/mod.rs.
  4. Python bindings in vortex-python:
    • GoosefsStore pyclass (mirroring CosStore) with the same keyword-only options as GoosefsConfig.
    • Extend AnyVortexStore to accept GoosefsStore in read_url / write.
    • vortex.store._goosefs module with a graceful ImportError placeholder when the opendal feature is disabled.
    • Add GoosefsStore to the .pyi type stub and to vortex.store.ObjectStore union + __all__.

Behavior contract

  • goosefs://<master-addr>:<port>/<path> → master address from the URL authority, root prefix optional from properties["root"].
  • goosefs:///<path> with GOOSEFS_MASTER_ADDR=10.0.0.1:9200 in the environment → store built from the env var.
  • master_addr empty after all fallback layers → OpenDALStoreError::MissingConfig("master_addr") (deterministic regardless of the process environment, using a fixed env_lookup in tests).
  • HA mode (master_addr="host1:9200,host2:9200,host3:9200") is accepted and the OpenDAL client uses PollingMasterInquireClient to discover the primary master.

Testing

  • Unit tests in vortex-cloud/src/opendal/goosefs.rs covering: missing master_addr, URL-authority fallback, env-var fallback, property override precedence, HA build, and explicit-config build.
  • Existing supports_scheme_tracks_enabled_features and every_supported_scheme_dispatches tests extended to cover the goosefs feature.
  • All 22 tests in vortex-cloud (cos + oss + goosefs) must pass with cargo test -p vortex-cloud --features cos,oss,goosefs.
  • cargo clippy -p vortex-cloud --features cos,oss,goosefs and cargo +nightly fmt --check must pass.

Dependency notes

  • No new direct workspace dependency required. goosefs-sdk v0.1.8 is pulled transitively through opendal-service-goosefs v0.57.0, which is what we want — pinning goosefs-sdk directly in the workspace would force a second upgrade every time opendal-service-goosefs bumps.
  • The PR targets develop with opendal = "0.57.0" and object_store = "0.13.2" (datafusion 54 compatible). A follow-up to bump opendal to 0.58.1 is tracked separately and depends on datafusion moving to object_store 0.14.

Additional context

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    featureA feature request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions