Skip to content

refactor(object-store): share one URL registry across Python, Java and DuckDB - #8999

Open
robert3005 wants to merge 5 commits into
developfrom
claude/opendal-integration-review-1h8f3a
Open

refactor(object-store): share one URL registry across Python, Java and DuckDB#8999
robert3005 wants to merge 5 commits into
developfrom
claude/opendal-integration-review-1h8f3a

Conversation

@robert3005

Copy link
Copy Markdown
Contributor

Rationale for this change

Follow-up to #8845, which added the OpenDAL-backed cos:// store.

URL-to-ObjectStore resolution had grown three independent implementations:

Caller Schemes Caching Credentials
vortex-python's Registry file, s3, azure, gcs, http, cos per-prefix case-insensitive env
vortex-jni's make_object_store file, s3, azure, gcs, cos per-URL property-driven builders
vortex-duckdb's resolve_filesystem file, s3 only none from_env only

Only the first knew about the OpenDAL-backed schemes, and it was pub(crate), so no Rust
consumer could reach it. Adding a provider meant touching every caller — which is exactly
what #8845 had to do, and what the next provider would have to do again.

This also unblocks a concrete gap: vortex-object-store-opendal was publish = false, so no
published crate could depend on it.

What changes are included in this PR?

Hoist the registry into vortex-io. vortex-python's private Registry becomes public
vortex_io::object_store::Registry, and the bindings point at it:

  • vortex-python drops its private copy (309 lines deleted) and uses the shared one.
  • vortex-duckdb replaces its file/s3-only match with the registry, gaining Azure, GCS,
    HTTP and per-bucket client reuse.
  • vortex-jni keeps its property-driven builders — they have S3 behaviour the registry does not
    reproduce — but asks supports_scheme instead of hard-coding "cos", so the call site stays
    correct as services are added.

Feature-gate the cloud stack. The registry lives behind a new object_store_registry
feature so plain file IO does not pull in the cloud HTTP stack: vortex-file with
object_store still resolves zero reqwest in its dependency tree.

Alibaba Cloud OSS. Added alongside COS, behind per-service cos / oss features. The crate
is split into per-service modules and gains supports_scheme / SUPPORTED_SCHEMES so callers
stop matching scheme strings. OSS reads ALIBABA_CLOUD_* (with the underscore) and has no
disable_config_load; its nearest knob, skip_signature, is exposed for public buckets.

Make vortex-object-store-opendal publishable, so published crates can depend on it.
opendal / object_store_opendal move to [workspace.dependencies] alongside every other
third-party dependency.

Remove ambient process state from tests. The registry takes its configuration from an
injected EnvSource, replacing the three unsafe std::env::set_var blocks the moved tests
used. set_var became unsafe in Rust 2024 precisely because cargo test runs tests on
multiple threads in one process; the suite now passes under a deliberately hostile environment.

Test coverage for the moved registry (vortex-io/src/object_store/registry/tests.rs, 8 tests):
resolution, per-key caching, Arc::ptr_eq on two objects in one bucket, prefix registration,
empty-path file://, registered-store-wins-over-build, and OpenDAL scheme dispatch.

What APIs are changed? Are there any user-facing changes?

New public Rust API:

  • vortex_io::object_store::Registry (+ Registry::new), gated on the new object_store_registry
    feature; re-exported as vortex::io::object_store::Registry.
  • vortex-io / vortex features object_store_registry and opendal.
  • vortex_object_store_opendal::{supports_scheme, SUPPORTED_SCHEMES, OSS_SCHEME, OssConfig, make_oss_store},
    and per-service cos / oss features. The crate is now published.
  • vortex-duckdb gains an opendal feature.

No Python-facing API change: vortex-python swaps a private implementation for the shared one.
DuckDB users gain Azure/GCS/HTTP scheme support that previously errored with
Unsupported URL scheme.

Checks

Check Result
cargo check -p vortex-object-store-opendal --all-features pass
cargo check -p vortex-io --all-features pass
cargo check -p vortex-python --all-features --all-targets pass
cargo check -p vortex-jni --all-features --all-targets pass
cargo check -p vortex --features files,tokio,object_store,object_store_registry pass
cargo test -p vortex-object-store-opendal --all-features 14 passed + 1 doctest
cargo test -p vortex-io --all-features 150 passed + 1 doctest
cargo test -p vortex-python --all-features --lib 5 passed
cargo clippy -p vortex-object-store-opendal -p vortex-io -p vortex-python -p vortex-jni --all-targets --all-features clean
cargo clippy -p vortex-object-store-opendal -p vortex-io --no-default-features clean
cargo +nightly fmt --all --check clean
cargo metadata --locked Cargo.lock up to date
uv run --all-packages make -C docs clean html build succeeded (--fail-on-warning)
uv run --all-packages make -C docs clean doctest 271 tests, 0 failures

Could not run locally: cargo check -p vortex-duckdb — the build script downloads DuckDB
source from github.com/duckdb/duckdb/archive, which returns 403 through this environment's proxy
(codeload.github.com too). The vortex-duckdb change is 2 files; I verified by inspection that
vortex::io::object_store::Registry is re-exported under the features the manifest requests, that
From<object_store::Error> for VortexError exists for the new ?, and that no import became
unused. CI's DuckDB jobs will be the first real compile of it.

cargo deny was also not run (failed to build locally). The new OSS dependencies
(opendal-service-oss, reqsign-aliyun-oss) are both Apache-2.0, matching the COS equivalents
already accepted in #8845.

🤖 Generated with Claude Code

https://claude.ai/code/session_012TyPy9MbKP2j546m1CaKLk


Generated by Claude Code

…d DuckDB

URL-to-ObjectStore resolution had grown three independent implementations:
`vortex-python`'s `Registry`, `vortex-jni`'s `make_object_store`, and
`vortex-duckdb`'s two-scheme match. Only the first knew about the
OpenDAL-backed schemes, and it was `pub(crate)`, so no Rust consumer could
reach it.

Hoist that registry into `vortex-io::object_store::Registry` as public API and
point the bindings at it:

- `vortex-python` drops its private copy and uses the shared one.
- `vortex-duckdb` replaces its `file`/`s3`-only match (no caching, no
  credentials beyond `from_env`) with the registry, gaining Azure, GCS, HTTP
  and per-bucket client reuse.
- `vortex-jni` keeps its property-driven builders, which have S3 behaviour the
  registry does not reproduce, but now asks `supports_scheme` instead of
  hard-coding `"cos"`.

The registry lives behind a new `object_store_registry` feature so that plain
file IO does not pull in the cloud HTTP stack: `vortex-file` with
`object_store` still resolves zero `reqwest` in its dependency tree.

Alibaba Cloud OSS support is added alongside the existing COS support, behind
per-service `cos` and `oss` features on `vortex-object-store-opendal`, which is
now publishable so that published crates can depend on it. The crate is split
into per-service modules and gains `supports_scheme` / `SUPPORTED_SCHEMES` so
callers stop matching scheme strings themselves. OSS reads `ALIBABA_CLOUD_*`
(with the underscore) and has no `disable_config_load`; its nearest knob,
`skip_signature`, is exposed for public buckets.

Store construction no longer depends on ambient process state in tests: the
registry takes its configuration from an injected source, replacing the three
`unsafe std::env::set_var` blocks the moved tests used. The suite now passes
with a deliberately hostile environment set.

Signed-off-by: "Claude" <robert@spiraldb.com>
@robert3005 robert3005 added the changelog/feature A new feature label Jul 27, 2026 — with Claude
Signed-off-by: Robert Kruszewski <github@robertk.io>
Signed-off-by: Robert Kruszewski <github@robertk.io>
@codspeed-hq

codspeed-hq Bot commented Jul 27, 2026

Copy link
Copy Markdown

Merging this PR will improve performance by 17.43%

⚠️ Unknown Walltime execution environment detected

Using the Walltime instrument on standard Hosted Runners will lead to inconsistent data.

For the most accurate results, we recommend using CodSpeed Macro Runners: bare-metal machines fine-tuned for performance measurement consistency.

⚡ 1 improved benchmark
✅ 1891 untouched benchmarks
⏩ 3 skipped benchmarks1

Performance Changes

Mode Benchmark BASE HEAD Efficiency
WallTime cuda/bitpacked_u8/unpack/3bw[100M] 351.5 µs 299.3 µs +17.43%

Tip

Curious why this is faster? Comment @codspeedbot explain why this is faster on this PR, or directly use the CodSpeed MCP with your agent.


Comparing claude/opendal-integration-review-1h8f3a (9dc7a81) with develop (b15394a)

Open in CodSpeed

Footnotes

  1. 3 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

Signed-off-by: Robert Kruszewski <github@robertk.io>
I, Claude <robert@spiraldb.com>, hereby add my Signed-off-by to this commit: c85a848

Signed-off-by: Claude <robert@spiraldb.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

changelog/feature A new feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant