Hi, Thank you Hongshun, I really appreciate your offer to help.
Also I created a page in Confluence: https://cwiki.apache.org/confluence/pages/viewpage.action?pageId=421957144 - Anton чт, 23 апр. 2026 г. в 13:38, Hongshun Wang <[email protected]>: > > Hi Anton, > Thank you very much for pushing this forward. I can help with it if needed. > +1 from my side.On Thu, Apr 23, 2026 at 3:28 PM Anton Borisov < > [email protected]> wrote: > > Best, > Hongshun > > > Hi Leonard, > > > > Thanks a lot for the support! Appreciate it > > > > Giannis has already granted me the Confluence permissions, so I will > > migrate > > this draft there. > > > > - Anton > > > > чт, 23 апр. 2026 г. в 09:14, Leonard Xu <[email protected]>: > > > > > > +1 from my side, the motivation and the proposed merge plan makes sense > > to me. > > > > > > Btw, could you left your jira account name? Anton, we can add the > > Confluence edit permission for you. > > > > > > Best, > > > Leonard > > > > > > > 2026 4月 23 14:50,Anton Borisov <[email protected]> 写道: > > > > > > > > Hi all, > > > > > > > > Following up on the 0.2.0-incubating roadmap thread, where the repo > > > > merge came through as the strongest priority signal, I am opening this > > > > as its own [DISCUSS] as promised. > > > > > > > > Per the consensus on that thread, 0.2.0 development continues on > > > > fluss-rust in parallel and is not blocked by this FIP. > > > > > > > > I do not currently have edit rights on the FLUSS Confluence space, so > > > > I am posting the full draft inline. Once discussion converges, a > > > > committer can paste the agreed text into a FIP-XX page. Please treat > > > > the text below as a working draft; I am happy to revise it as feedback > > > > comes in. > > > > > > > > =============================================================== > > > > FIP-XX: Consolidate apache/fluss-rust into apache/fluss > > > > > > > > Discussion thread: this thread > > > > Vote thread: TBD > > > > Release: Fluss 1.0 (target) > > > > Status: Under Discussion > > > > > > > > Motivation > > > > ============= > > > > > > > > Fluss source code currently lives in two ASF repos. > > > > > > > > 1.1 Current layout today > > > > > > > > apache/fluss > > > > ├─ fluss-server/ > > > > ├─ fluss-client/ > > > > ├─ fluss-rpc/ > > > > │ └─ src/main/proto/*.proto > > > > ├─ fluss-flink/, fluss-spark/, ... > > > > ├─ website/ > > > > │ └─ fluss.apache.org > > > > └─ .github/workflows/ > > > > > > > > apache/fluss-rust > > > > ├─ crates/fluss/ > > > > │ └─ src/proto/*.proto > > > > │ hand-ported subset > > > > ├─ bindings/python/ > > > > ├─ bindings/cpp/ > > > > ├─ bindings/elixir/ > > > > ├─ website/ > > > > │ └─ clients.fluss.apache.org > > > > └─ .github/workflows/ > > > > > > > > fluss-rust was incubated in its own repo so the Rust core could move > > > > quickly. With 1.0 GA on the horizon, the costs of the split now exceed > > > > the benefit. > > > > > > > > As discussed on the 0.2.0 thread, 1.0 should represent the complete > > > > form of the project: all language SDKs and unified release > > > > coordination from a single repository, to signal maturity to users. A > > > > fragmented multi-repo layout at GA undermines that message. > > > > > > > > 1.2 Concrete costs today > > > > > > > > Protobuf schema is duplicated and can diverge. The source of truth is > > > > fluss-rpc/src/main/proto/FlussApi.proto (package fluss). > > > > fluss-rust carries a hand-maintained subset at > > > > crates/fluss/src/proto/fluss_api.proto (package proto). > > > > The subset exists only because the two repos cannot share files; > > > > nothing enforces consistency. > > > > > > > > Server version is pinned manually in two files: > > > > crates/fluss-test-cluster/test-images.env and > > > > bindings/elixir/test/support/cluster.ex, both pointing today to > > > > apache/fluss:0.9.0-incubating, with no automation. > > > > > > > > Docs are split across two subdomains. fluss.apache.org/docs/apis/ > > > > *-client.md pages are stubs that link out to > > > > clients.fluss.apache.org/user-guide//... This means two > > > > Docusaurus builds and two deployment pipelines. > > > > > > > > Infrastructure is duplicated: 8 CI workflows in each repo, > > > > duplicated LICENSE / NOTICE / DISCLAIMER files at repo root, and > > > > two release trains. > > > > > > > > Cross-repo changes cost two PRs, two reviews, and a Docker image cut > > > > per wire-protocol change. > > > > > > > > 1.3 ASF peer evidence > > > > > > > > ASF peer evidence points the other way: mature ASF projects > > > > overwhelmingly colocate language bindings with core. > > > > > > > > Apache Thrift -> apache/thrift/lib/{java,py,cpp,rs,go,rb,...} > > > > > > > > Apache Avro -> apache/avro/lang/{java,py,c,rust,ruby,...} > > > > > > > > Apache Beam -> apache/beam/sdks/{java,python,go,typescript} > > > > > > > > PyFlink -> apache/flink/flink-python/ > > > > > > > > PySpark -> apache/spark/python/ > > > > > > > > Apache Arrow is the visible counter-example: arrow-rs, arrow-go, > > > > arrow-java, and arrow-js live in separate repos. Apache Avro also > > > > externalized its Go binding (apache/avro-go) on a similar trajectory. > > > > In both cases, the split happened after the format stabilized and > > > > after the specific language community had grown large enough to > > > > self-sustain. > > > > > > > > Fluss is at neither milestone. The wire protocol is still evolving > > > > aggressively pre-1.0, and the Rust, Python, C++, and Elixir bindings > > > > are all co-maintained by the same contributors. Splitting now incurs > > > > coordination overhead that Arrow and Avro only accepted at maturity, > > > > without yet having their enabling conditions. > > > > > > > > The Flink connector-externalization retrospective is sometimes cited, > > > > but does not really apply: connectors are N external-system > > > > integrations maintained by independent communities, not N language > > > > wrappers over one wire protocol. > > > > > > > > Public interfaces > > > > ==================== > > > > > > > > None. Published artifacts remain unchanged: > > > > > > > > Maven Central: org.apache.fluss:fluss-* > > > > > > > > crates.io: fluss-rs > > > > > > > > PyPI: pyfluss > > > > > > > > git: Elixir fluss (planned hex.pm publication) > > > > > > > > CMake / Bazel: fluss-cpp > > > > > > > > Proposed changes > > > > =================== > > > > > > > > Jark outlined the merge as five workstreams: code migration, CI > > > > unification, documentation restructuring, issue migration, and > > > > contributor workflow changes. Sections 3 and 4 address each. > > > > > > > > 3.1 Code migration - target layout > > > > > > > > apache/fluss/ > > > > ├─ fluss-server/ (Java, unchanged) > > > > ├─ fluss-client/ (Java, unchanged) > > > > ├─ fluss-rpc/ (single .proto source; see 3.4) > > > > │ └─ src/main/proto/FlussApi.proto > > > > ├─ fluss-flink/, fluss-spark/, ... (Java modules, unchanged) > > > > ├─ fluss-rust/ (new: today's apache/fluss-rust tree) > > > > │ ├─ Cargo.toml, Cargo.lock > > > > │ ├─ crates/{fluss, examples, fluss-test-cluster}/ > > > > │ ├─ bindings/{python, cpp, elixir}/ > > > > │ ├─ justfile, MODULE.bazel, rust-toolchain.toml, > > > > │ │ deny.toml, rustfmt.toml > > > > │ └─ scripts/ > > > > ├─ website/ (unified Docusaurus; see 3.3) > > > > └─ .github/workflows/ (unified with path filters; see 3.2) > > > > > > > > fluss-rust mirrors sibling naming such as fluss-server/ and > > > > fluss-flink/. Bindings stay nested because they share a Cargo > > > > workspace, rust-toolchain.toml, deny.toml, and workspace-level > > > > dependency resolution with the Rust core. > > > > > > > > 3.2 CI unification > > > > > > > > A single .github/workflows/ directory. Path filters are a hard > > > > requirement: > > > > > > > > Java CI: pom.xml, fluss-*/** (excluding fluss-rust/), tools/** > > > > > > > > Rust core CI: fluss-rust/Cargo.*, fluss-rust/crates/** > > > > OR fluss-rpc/src/main/proto/** > > > > > > > > Binding CI: fluss-rust/bindings//** > > > > OR fluss-rpc/src/main/proto/** > > > > > > > > Docs build: website/** > > > > > > > > Existing release workflows move over unchanged. Their triggers are > > > > tag-based and already disjoint from each other. > > > > > > > > 3.3 Documentation restructuring > > > > > > > > fluss/website/docs/ > > > > ├─ intro.md > > > > ├─ quickstart/ > > > > ├─ concepts/ > > > > ├─ clients/ (new section) > > > > │ ├─ support-matrix.md > > > > │ ├─ java/ > > > > │ ├─ rust/ > > > > │ ├─ python/ > > > > │ └─ cpp/ > > > > ├─ engine-flink/, engine-spark/, ... > > > > └─ ... > > > > > > > > clients.fluss.apache.org is retired. Redirects from old paths use > > > > @docusaurus/plugin-client-redirects, with mappings generated by > > > > walking the two sidebars.ts files. The > > > > fluss-rust/.github/workflows/deploy_documentation.yml workflow is > > > > removed; deployment converges on the existing fluss/website -> > > > > apache/fluss-website dispatch. > > > > > > > > 3.4 Protobuf single source of truth > > > > > > > > Today, crates/fluss/src/proto/fluss_api.proto exists as a > > > > hand-maintained subset of the Java-side canonical proto solely because > > > > the two repos could not share files. The merge removes that > > > > constraint, and this FIP removes the subset. > > > > > > > > After the structural merge: > > > > > > > > Delete fluss-rust/crates/fluss/src/proto/fluss_api.proto. > > > > > > > > Point fluss-rust/crates/fluss/build.rs at the canonical proto: > > > > > > > > config.compile_protos( > > > > &["../../../fluss-rpc/src/main/proto/FlussApi.proto"], > > > > &["../../../fluss-rpc/src/main/proto"], > > > > )?; > > > > > > > > Update the .bytes() prefixes in build.rs from ".proto." to > > > > ".fluss." because the canonical proto declares package fluss. > > > > > > > > Update lib.rs include! from "/proto.rs" to "/fluss.rs", since > > > > prost names the generated file after the proto package. > > > > > > > > The vendored copy exists only to satisfy crates.io packaging rules; > > > > the monorepo build reads the canonical proto directly. For crates.io > > > > publishing, vendor the canonical .proto into the crate at > > > > cargo-publish time via scripts/release.sh, with build.rs falling > > > > back to the in-crate copy when the monorepo path is absent. > > > > > > > > All existing crate::proto::TypeName call sites compile unchanged, > > > > because the pub mod proto { ... } wrapper in lib.rs preserves the > > > > import path. > > > > > > > > After this, adopting a new server RPC becomes a single-PR change: the > > > > message lands in the canonical proto and Rust types appear > > > > automatically. Nothing remains to drift against, so no CI drift-gate > > > > is needed. Section 6 covers why a drift-gate alone would be the wrong > > > > answer. > > > > > > > > 3.5 Release cadence > > > > > > > > Java server and Rust client keep their current independent SemVer > > > > cadences until 1.0 GA. From 1.0 onward, both trees cut a jointly > > > > numbered X.Y.Z release from a single tag; patch releases can still > > > > ship independently where scope is binding-only or server-only. > > > > Binding-specific SemVer continues where public APIs diverge, for > > > > example if a pyfluss major bump is driven by PyO3 ABI changes. > > > > > > > > Open to revision: the post-1.0 release model is listed in section 8 > > > > and likely deserves its own [DISCUSS] once this FIP lands. > > > > > > > > Compatibility, deprecation, and migration plan > > > > ================================================= > > > > > > > > 4.1 Phases > > > > > > > > [0 Agreement] -> [1 Dry run] -> [2 Merge window] -> [3 Archive] -> [4 > > Cleanup] > > > > > > > > DISCUSS + VOTE > > > > > > > > fork dry run > > > > > > > > follow-up PRs > > > > > > > > redirects > > > > > > > > INFRA ticket > > > > > > > > Agreement. This FIP's DISCUSS + VOTE. INFRA ticket filed and > > > > resolved before VOTE is called, so the migration plan is confirmed > > > > viable rather than assumed. > > > > > > > > Dry run on a fork: verify CI, path filters, docs build, redirects, > > > > and git log --follow across the boundary. > > > > > > > > Merge window. Short freeze on apache/fluss-rust; structural merge > > > > commit into apache/fluss. Protobuf (3.4) and docs (3.3) > > > > consolidation land as separate follow-up PRs for reviewability. > > > > > > > > Archive. INFRA archives apache/fluss-rust read-only; issues, PRs, > > > > commits, and tags remain as permalinks. Subdomain redirects go > > > > live. A pinned README on the archived repo points to apache/fluss, > > > > since GitHub does not forward content-moves between repos > > > > automatically. > > > > > > > > Cleanup. Consolidate root-level duplicates such as LICENSE / > > > > NOTICE / DISCLAIMER and contributor docs. > > > > > > > > 4.2 History preservation > > > > > > > > On a clone of apache/fluss-rust: > > > > > > > > git filter-repo --to-subdirectory-filter fluss-rust > > > > > > > > In apache/fluss: > > > > > > > > git remote add rust ../fluss-rust-rewritten > > > > git fetch rust > > > > git merge --allow-unrelated-histories --no-ff rust/main > > > > > > > > This preserves git log --follow and git blame --follow on every > > > > rewritten file. git subtree breaks log --follow on files inside the > > > > subtree; git filter-branch is deprecated. > > > > > > > > 4.3 Issue migration > > > > > > > > Closed issues and PRs remain at their apache/fluss-rust archive URLs > > > > as permalinks. Open issues at merge time are re-filed in apache/fluss > > > > with cross-links, scripted via gh CLI. Open PRs are reopened by their > > > > authors against the new path; GitHub does not support cross-repo PR > > > > transfer. > > > > > > > > 4.4 Contributor workflow > > > > > > > > Contributors re-clone and re-open in-flight PRs against the new path. > > > > Downstream artifact consumers see no change. Docs visitors follow > > > > redirects. > > > > > > > > 4.5 Timeline > > > > > > > > There is no dependency on a specific release. Target completion is > > > > before 1.0 GA, per the fluss-rust roadmap 0.2.0 DISCUSS consensus. > > > > Within that bound, the community can pick the window that minimizes > > > > rebase pain, most likely after 0.2.0-incubating is cut, to avoid > > > > forcing in-flight roadmap work to rebase across the merge. > > > > > > > > Test plan > > > > ============ > > > > > > > > In the merged repo, CI runs the full Java + Rust + all-binding > > > > matrices on every PR. > > > > > > > > Path-filter correctness is explicitly tested: a Rust-only PR must > > > > not trigger Java jobs, and vice versa. > > > > > > > > Protobuf: a change to fluss-rpc/src/main/proto/FlussApi.proto alone > > > > produces a green Rust build with no Rust-side edit, confirming the > > > > single-source claim. > > > > > > > > Docs: every fluss-rust/website/docs/user-guide/... page renders > > > > under fluss.apache.org/docs/clients/...; sampled old URLs redirect. > > > > > > > > History: git log --follow on a sample migrated file shows full > > > > pre-merge history. > > > > > > > > Rejected alternatives > > > > ======================== > > > > > > > > Status quo. The section 1 costs recur every release cycle and grow > > > > with each new binding. > > > > > > > > Drift-gate instead of full proto consolidation. Keep the Rust > > > > subset and add CI to flag divergence on messages present in both > > > > files. Rejected because it catches only half the drift problem, > > > > preserves a hand-maintained file whose only reason to exist was the > > > > cross-repo constraint the merge removes, and adds custom comparison > > > > logic to maintain. > > > > > > > > Polyglot-repo federation, Iceberg-style. This works for Iceberg > > > > because bindings have independent maintainer communities and the > > > > table-format spec is stable enough that protocol-evolution coupling > > > > is low. Neither holds for Fluss pre-1.0: bindings are co-maintained > > > > by the same team, and the wire protocol is still evolving > > > > aggressively. For Fluss in the run-up to 1.0, locking bindings to > > > > server evolution is a feature, not a bug. > > > > > > > > Apache Arrow precedent (arrow-rs split, 2021). > > > > https://arrow.apache.org/blog/2021/05/04/rust-dev-workflow/ > > > > Section 1 covers the structural frame: Arrow split after > > > > stabilization and after each binding had grown an autonomous > > > > community. Arrow's specific 2021 rationale also inverts for Fluss. > > > > > > > > Git submodules. Standard UX problems and does not solve the docs > > > > split. > > > > > > > > Further splitting into per-binding repos. This multiplies every cost > > > > listed in section 1. > > > > > > > > Flatten bindings to the top level of the merged repo. This breaks > > > > the shared Cargo workspace. Keeping them under fluss-rust/ > > > > preserves it; rearrangement remains an option later. > > > > > > > > Risks > > > > ======== > > > > > > > > CI blast radius if path filters are misconfigured. Mitigated by > > > > sections 3.2 and 5. > > > > > > > > In-flight PRs stall during the freeze. Mitigated by maintainers > > > > proactively reopening high-value PRs. > > > > > > > > Open questions > > > > ================= > > > > > > > > Directory name for the Rust tree. Proposal: fluss-rust/ > > > > (mirrors fluss-server/ and fluss-flink/ sibling naming). > > > > Alternatives: rust/, clients/rust/. > > > > > > > > Docs section name. Proposal: docs/clients/ to unify client and > > > > binding docs under one heading, while keeping docs/engine-*/ for > > > > pipeline integrations. Alternative: keep docs/apis/ to reduce link > > > > churn during migration. > > > > > > > > Post-1.0 release model. Section 3.5 proposes synchronized X.Y.Z > > > > across Java and Rust with independent patches. Alternative: > > > > Arrow-style coordinated-but-independent versioning. This likely > > > > deserves its own [DISCUSS] once this FIP lands. > > > > > > > > Looking forward to feedback. > > > > > > > > Best, > > > > Anton > > > > >
