Skip to content

Support local UMDK headers in Bazel - #19

Closed
cw20050111-prog wants to merge 27 commits into
LinQuickDev:urma_transportfrom
cw20050111-prog:urma_transport_dev
Closed

Support local UMDK headers in Bazel#19
cw20050111-prog wants to merge 27 commits into
LinQuickDev:urma_transportfrom
cw20050111-prog:urma_transport_dev

Conversation

@cw20050111-prog

Copy link
Copy Markdown

What problem does this PR solve?

Issue Number: resolve 3428

Problem Summary:

Address review comments around URMA Bazel support. Previously Bazel always
resolved @umdk through a fixed git_repository, so it could not prefer a
locally installed UMDK SDK, could not disable fallback downloads for offline CI,
and the documentation suggested --distdir even though @umdk was git-based.

What is changed and the side effects?

Changed:

  • Replace the fixed Bazel @umdk git_repository with umdk_repository.
  • Support URMA_ROOT for local UMDK headers in both bzlmod and WORKSPACE mode.
  • Fall back to the pinned UMDK git revision only when URMA_ROOT is not set.
  • Support --repo_env=BRPC_DOWNLOAD_URMA_HEADERS=false to fail early instead of downloading.
  • Update English and Chinese URMA docs with Bazel-specific build instructions.
  • Clarify that --distdir does not apply to the git fallback, and document --override_repository=umdk=... only for prepared Bazel repositories.
  • Keep real URMA and mock builds separated through the existing explicit mock switch.

Side effects:

  • Performance effects: No runtime performance impact. Bazel repository resolution may use local headers when URMA_ROOT is set, avoiding network access.
  • Breaking backward compatibility: No. The default behavior still downloads the same pinned UMDK revision when URMA_ROOT is not set.

Validation:

  • bazel query --repo_env=URMA_ROOT=/private/tmp/brpc_fake_umdk @umdk//:urma_headers
  • bazel query --noenable_bzlmod --repo_env=URMA_ROOT=/private/tmp/brpc_fake_umdk_src @umdk//:urma_headers
  • bazel query --repo_env=BRPC_DOWNLOAD_URMA_HEADERS=false @umdk//:urma_headers fails as expected without URMA_ROOT
  • bazel build --nobuild --repo_env=URMA_ROOT=/private/tmp/brpc_fake_umdk_src --define BRPC_WITH_URMA=true //:brpc
  • bazel build --nobuild --repo_env=URMA_ROOT=/private/tmp/brpc_fake_umdk_src --define BRPC_WITH_URMA=true --define BRPC_WITH_URMA_MOCK=true //:brpc
  • git diff --check

Check List:

cw20050111-prog and others added 13 commits August 21, 2026 14:25
…works

The umdk repo ships its own src/urma/BUILD.bazel, which makes Bazel
treat src/urma/ as a separate package. glob() in our umdk.BUILD
(rooted at the umdk repo root) can't cross that boundary, so
hdrs = glob(["src/urma/lib/urma/**/include/*.h"]) silently resolved to
an empty list. The cc_library then exported no header inputs, so
compiling anything that #includes urma_api.h failed with "No such
file or directory" even though the -isystem path was correct and the
file existed on disk.

Confirmed via GitHub Actions on both ubuntu-22.04 (x86_64) and
ubuntu-24.04-arm (arm64): `bazel build --define=BRPC_WITH_URMA=true //:brpc`
failed identically on both before this patch_cmds fix.
Reviewer dwh110 pointed out that src/brpc/urma/mock_urma.cpp had no
independent feature switch: whenever liburma wasn't found, CMake/Make
silently linked the mock, which can produce a binary that looks
URMA-capable but can't reach real hardware.

Add WITH_URMA_MOCK (CMake) / --with-urma-mock (config_brpc.sh),
default OFF. When WITH_URMA is enabled and liburma isn't found, the
build now fails with a clear message unless the mock is explicitly
requested, instead of substituting it implicitly. Document the new
flag in docs/en/urma.md and docs/cn/urma.md.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Add conditional linking for URMA library based on availability.
Added a comment regarding linking with liburma based on brpc build options.
Added logic to find the URMA library and handle its absence.
Removed conditional check for URMA library and related messages.
Update logic for linking liburma based on header presence.
Comment thread .gitignore
/test/out.txt
/test/recordio_ref.io

# Local design notes and Graphify artifacts.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

gitignore不需要携带个人的配置到社区

Add local design notes and Graphify artifacts to .gitignore
Ensure bond_include is always symlinked, adding a check for its presence.
…C++14 clean

The cmake-unittest-urma-mock CI job failed to compile: the urma_user_ctl()
mock added in 9b540ac was pasted into the middle of urma_create_context(),
so the file had a function definition nested inside another function
("error: a function-definition is not allowed here before '{' token").
Move urma_user_ctl() out to file scope, after urma_create_context().

While verifying the fix, the same sources were built the way a real
deployment builds them (Makefile path, -std=c++14, --werror) and three
further problems showed up:

* mock_urma.cpp used std::shared_mutex, which is C++17. config_brpc.sh
  pins -std=c++14, so `--with-urma --with-urma-mock` could not compile at
  all outside CMake. Use std::shared_timed_mutex (C++14, same reader/
  writer semantics) behind a MockSharedMutex alias.
* mock_urma.cpp ignored the results of write()/read() on the JFCE eventfd
  with a plain (void) cast, which glibc's warn_unused_result still
  diagnoses; capture the result instead.
* urma_endpoint.cpp compared a signed bthread_tag_t against
  _poller_groups.size() (-Wsign-compare), and brpc_urma_unittest.cpp
  memset() a ParsedHello, which is non-trivial (-Wclass-memaccess).

Add a make-compile-urma-mock CI job so the C++14/--werror combination is
covered from now on; the existing CMake job builds with the compiler's
default standard and cannot catch it.

Verified locally: CMake mock build + ctest, CMake build against a real
liburma.so (mock compiled as a shared library standing in for the SDK),
and the Makefile build of every URMA object with --werror --with-urma
--with-urma-mock. All 14 brpc_urma_unittest cases pass in both CMake
configurations.
WITH_URMA_MOCK=ON was silently ignored on any machine that has liburma
installed: CMake checked "is liburma found?" first and only consulted the
switch in the not-found branch. config_brpc.sh had the same inversion.

That makes a mock build mean different things on different machines --
the mock on a CI image without liburma, a hardware build on a developer
box that happens to have the SDK -- which is exactly the "the mock lacks
an independent feature switch" problem the switch was added to solve. It
also disagreed with Bazel, where brpc_with_urma_mock is a specialization
of brpc_with_urma and therefore already wins whenever both defines are
set.

Check the explicit opt-in first, so all three build systems agree. When
the switch overrides a real liburma, CMake emits a WARNING and
config_brpc.sh an info line naming the library being bypassed. Not
finding liburma without the switch still fails the build, unchanged.

Found on an aarch64 box with umdk-urma installed: -DWITH_URMA_MOCK=ON
configured as mock=0 there, leaving the mock side of the build
unbuildable and untestable.
On CTP -- which is what brpc advertises in MakeLocalParsedHello -- a
single URMA SEND may not carry more than 4096 bytes. Over-size WRs are
not rejected by urma_post_jetty_send_wr: the call succeeds and reports a
successful completion, but the payload never arrives intact, so the
peer's parser waits forever for bytes that never come. The RPC only
fails on timeout, with clean logs on both ends.

The send path previously bounded a WR only by the peer's advertised recv
block size (urma_buffer_size - sizeof(IOBuf::Block), 8160 by default) --
twice the real limit. Clamp it by the transport limit as well so larger
messages are split across WRs. No protocol or handshake change is
needed: the receiver already appends each completion to _read_buf in
order and the protocol parser reassembles them, exactly as it does today
for messages larger than one recv block.

The device's own dev_cap.max_msg_size cannot be used as this bound.
Measured on aarch64 with umdk-urma 26.06.0-B020 the device reports
65536, yet every message above 4096 fails on the wire.

Also:
- add --urma_max_msg_size so the bound can be raised where the transport
  really does carry larger messages, still clamped by the device value;
- report the full completion record (direction, opcode, lengths, jetty
  ids, window state) when a WR fails instead of a bare status number,
  and map urma_cr_status_t to a readable name;
- zero-initialize the on-stack SGE array -- cut_into_sglist() sets
  addr/len/tseg but never user_tseg.

Verified across two aarch64 nodes over real URMA hardware: with the cap
in place every attachment size from 0 to 1MB completes with zero errors;
with the cap raised to the device-reported 65536, everything from 4096
up fails. Single-node loopback behaves differently from a real link and
must not be used to validate this path.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants