mirror of
https://github.com/Tencent/flare.git
synced 2026-10-16 20:31:05 +08:00
master
147 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
81386ff632 |
testing: drop SO_REUSEADDR from the port-availability probe (#214)
PickAvailablePort()/PickAvailableEndpoint() probe a candidate port by binding to it, but the probe socket set SO_REUSEADDR before binding 0.0.0.0:port. On macOS/BSD that lets the probe succeed even while another process (e.g. a sibling test's server) already holds 127.0.0.1:port, falsely reporting the port as free. The caller then binds its real server to the same port and fails with EADDRINUSE. This only surfaces under parallel test execution, where multiple tests grab ports concurrently -- e.g. logging_test failing with "Cannot bind socket to [127.0.0.1:5136]. : Address already in use" when run alongside server_test/server_group_test/integration_test. An availability probe must observe the port exactly as a fresh server bind would, so it must not set SO_REUSEADDR. Without it, an occupied port is correctly rejected and PickAvailablePort() retries another random port. Verified with a deterministic repro (occupied 127.0.0.1:P; probe with SO_REUSEADDR reports free, without it reports occupied) and by stress-running the four port-grabbing rpc tests in parallel. Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
8833dfa279 |
base: never-destroy tls_queues to fix an exit-time mutex crash (#213)
* base: never-destroy tls_queues to fix an exit-time mutex crash
A static `MonitoredTimer` (and similar globals) calls
DeleteThreadOutOfDutyCallback in its destructor during static destruction, which
locks the `tls_queues` ThreadLocal's internal mutex. `tls_queues` was a plain
namespace static, so on macOS it could already be destroyed by then, and
std::mutex::lock() throws std::system_error EINVAL ("mutex lock failed") ->
std::terminate at process exit. monitoring_test reproduced this reliably
(all cases pass, then SIGABRT on shutdown).
Wrap it in NeverDestroyed, exactly as GetGlobalQueue() already does in the same
file, so the lock stays valid for the whole process lifetime. Leaking it is
harmless (the OS reclaims it at exit).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* base: clang-format the tls_queues comment
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
|
||
|
|
6320851cd6 |
thirdparty: make foreign_build.bld Starlark-parseable (#212)
blade-go's front-end is Starlark, which (unlike Python) has no generator expressions or implicit string concatenation. Convert foreign_build.bld to the equivalent Starlark forms so it can be include()'d there, with no behavior change under Python Blade: - generator expr -> list comprehension in the rpath ' '.join(...). - adjacent-string-literal concatenation -> explicit '+' in dyld_path, the autotools configure command, and the cmake generate command (parenthesized so the trailing `% (...)` still applies to the whole concatenation). - fix cmake_cc_library, which was dead-but-unparseable: it referenced undefined package_name/deps/with_packages. Give it deps/with_packages params, pass package_name=name and source_package through (mirrors autotools_cc_library). Same Starlark-compat class as the cc_flare_library change in the build_rules.bld. Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
3a5c410c18 |
build: make cc_flare_library front-end-agnostic; upgrade vendored blade (#211)
Rewrite the two Python-only constructs in the cc_flare_library extension so it parses under a Starlark front-end as well as Blade's (restricted) Python DSL, with identical behaviour under Blade: - `assert len(srcs) == 1, msg` -> `if len(srcs) != 1: fail(msg)` - `deps is None` -> `deps == None` - implicit adjacent-string concatenation -> explicit `+` `isinstance` is kept (both front-ends provide it). This lets flare build under a Go reimplementation of Blade (blade-go) without changing the current build. Also upgrade the vendored blade (thirdparty/blade/blade.zip + GITVERSION) to blade-build master, which adds the `fail()` builtin the change above uses. Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
71698ba232 |
thirdparty: pin AR/RANLIB in autotools foreign builds (fix macOS jemalloc link) (#210)
_configure passed CC/CXX from the resolved toolchain but let AR/RANLIB fall through to PATH. On macOS, a stray GNU-format `ar` ahead of /usr/bin/ar (e.g. Homebrew binutils / an llvm-ar in --format=gnu mode) builds a package's static archive in GNU format -- with `/` and `//` index members -- which Apple's ld rejects at link time: ld: archive member '/' not a mach-o file in '.../lib/libjemalloc.a' This surfaced on je_server (jemalloc's libjemalloc.a is built by a direct $(AR) crus Makefile rule, so it picks up the PATH ar; libtool-built archives like libtcmalloc/jsoncpp/ctemplate were unaffected because libtool drives the archiver consistently). The gperftools profiler archives hit the same GNU format but are gated Linux-only, so they never reached a macOS link. Pin AR/RANLIB the same way CC/CXX already are: force the system BSD ar/ranlib on macOS (they emit a `__.SYMDEF` archive ld accepts), and honor the toolchain ar elsewhere (GNU archives are fine for GNU ld). Passed both as env and as autoconf precious-vars so the generated Makefile uses them (verified: `AR = /usr/bin/ar`, archive members are `__.SYMDEF SORTED` + objects, je_server links). Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
be265c3307 |
rpc: de-flake Server.OverloadTest{,NoCreateSpecialMessage} (#209)
`ASSERT_EQ(100, succeeded)` over N racing calls against a 100-slot cap is timing-dependent: the handler slept a fixed 2s, so on a busy/slow runner the first sleepy handlers finish and free slots before all N calls are submitted, letting more than the cap succeed (CI saw 300/400). Being a *fatal* assert, the failure also skipped `gate->Stop()`/`server.Stop()`, leaving in-flight calls and crashing the next test (SIGSEGV). Make it deterministic: SleepyEchoService now *holds* its concurrency slot until released (bumping an `admitted` counter on entry). Each test fires exactly the cap (100) with a long deadline, waits until the cap is full, then floods the rest with a short deadline -- all dropped, since the cap is held. Once those drain, it releases the held calls: precisely the cap's worth succeed, no extra slips into a freed slot, and nothing times out -- independent of runner speed. Also switch to EXPECT_EQ so a failure can't skip teardown. Verified: passes 10/10 under heavy CPU load (was consistently failing on the busy CI runner); ~1.1s each (down from ~3.1s). |
||
|
|
91a27b93e5 |
thirdparty/blade: bump vendored blade to v3.0.0 (dd0d2ae) (#208)
Blade 3.0.0 is released. Bump the vendored blade from 3100733 (2026-06-23) to the 3.0.0 release commit dd0d2ae (2026-06-27): regenerated blade.zip via dist_blade and updated GITVERSION. |
||
|
|
8967316d93 |
object_pool: drop over-alignment of TLS LocalPoolDescriptor (UBSan) (#207)
`LocalPoolDescriptor` was `alignas(hardware_destructive_interference_size)` to keep its hot `objects` head off neighbouring cache lines, but its only instances live in thread-local storage (`GetLocalPoolDescriptor`). TLS does not honour over-alignment (> max_align_t) on several platforms (notably darwin), so the object was actually placed misaligned and every member access in `Get`/`Put` was undefined behaviour. UBSan reports it as memory_node_shared.h: member access within misaligned address ... for type 'LocalPoolDescriptor', which requires 64 byte alignment and, because every allocation in flare goes through this pool, it aborts 21 flare/base tests under `--sanitizer=undefined` (crypto, buffer, monitoring, object_pool, net, ...). Since the over-alignment was never honoured, the intended false-sharing isolation never happened -- so dropping it removes the UB at no real cost (the placement was never aligned anyway) and keeps the existing TLS storage semantics (the descriptor's storage must outlive its destructor, which poisons `current_` so late `Put`s during thread teardown take the safe slow path). Real cross-thread isolation here would need a different, persistent-aligned-storage mechanism. Verified: `flare/base/... --sanitizer=undefined` is all green (was 21 failing); normal build unaffected. |
||
|
|
6504d13b7b |
base: make heavy tests pass under sanitizers; fix latch_test data race (#206)
* base: make heavy tests pass under sanitizers; fix latch_test data race Running `flare/base/...` under `--sanitizer=thread` surfaced one test-side data race and three tests too heavy to finish under instrumentation: - latch_test: `TEST(Latch, Torture)` runs `RunTest` on 10 threads, each ending with `std::cout << ...`; concurrent formatted output races the stream buffer. Serialize that line with a mutex. - spinlock_test: 100 threads x 100k contended lock cycles -- under a sanitizer each contended acquire spins an unbounded, instrumented number of times, so the run takes many minutes (well past the test timeout). The brute-force volume is the race detector in a non-sanitized build, so keep it there and scale down (8 threads x 2k) only under ASan/TSan, following the existing `scheduling_group_test` pattern (FLARE_INTERNAL_USE_ASAN/TSAN). - compression_test / view_test: their 10 MiB workloads (LargeSize, VariantSize's ~9.5k-size sweep, the noncontiguous-buffer searches) are slow to instrument and time out under parallel sanitizer runs. These are large-data, not brute-force-race, tests, so just shrink them unconditionally to sizes that still exercise the multi-block / cross-block paths (512 KiB, ~1 MiB, a coarser size sweep). The 2 GiB extreme stays covered by DISABLED_HugeSize. Verified: `flare/base/... --sanitizer=thread` is all green; the normal build is unaffected (full-size workloads still run there, except the unconditionally shrunk compression/view). * base/thread: add annotation dep to spinlock_test in BUILD.bazel spinlock_test.cc now includes flare/base/internal/annotation.h (for the ASan/TSan workload guard); the blade BUILD got the dep but the Bazel build needs it too. |
||
|
|
48d793e6ab |
base/internal: fix data race on JobQueue::node_id_ (TSan) (#205)
`JobQueue::node_id_` was a plain `int`, written by the owner thread in `Push`'s periodic bookkeeping (`node_id_ = numa::GetCurrentNode()`) and read concurrently by the flusher thread in `FlushDpcs` (`GetNode()` -> `BackgroundTaskHost::Queue`) -- a data race. ThreadSanitizer reports it (size-4 read/write), aborting any test that drives DPC, e.g. dpc_test and the monitoring tests (which flush via `MonitoredTimer::FlushBufferedReports` -> `QueueDpc`). The field is only a NUMA hint (which background queue to dispatch the flush to), so a stale read merely picks a less-ideal queue. Make it a relaxed `std::atomic<int>`: race-free, no ordering required, no measurable cost. |
||
|
|
eb4ba86a6a |
future: bound InlineExecutor recursion depth to avoid stack overflow (#204)
A long Future continuation chain resolved through the (default) InlineExecutor recurses one frame per link -- SetBoxed -> Execute -> action -> SetBoxed -> ... -- and overflows the stack. It shows up around ~10k links (FutureV2Test.Chaining chains 10000) and triggers much sooner under AddressSanitizer, which inflates stack frames: `AddressSanitizer: stack-overflow` in Core::SetBoxed. Keep the historical re-entrant (synchronous, nested) execution -- some callers, notably streaming RPC, rely on a completion running its continuation before control returns -- but bound it: up to kMaxInlineDepth (128) re-entrant levels run nested as before; past that a job is queued and drained by the outermost frame (a trampoline), so the stack stays bounded while an unbounded chain still completes. Realistic chains never reach the limit and behave exactly as before; only a pathologically deep chain trades its deepest nesting for deferral, and a linear chain's order is unchanged either way. Verified: future tests pass with and without ASan (Chaining no longer overflows), fiber suite and flare/base all green. The thread_local state assumes an inline job does not suspend a fiber mid-execution (these continuations run synchronously). |
||
|
|
92f15f5412 |
thirdparty/blade: bump vendored blade to 3100733 (#203)
Catches flare's vendored blade up to blade-build master (from 34883163). What this pulls in, user-visible: - Cross-platform PGO: instrumentation (--profile-generate/--profile-use) and sample-based AutoFDO (--autofdo-generate/--autofdo-use) on gcc/clang, plus native MSVC (LTCG PGO / SPGO). Opt-in; no effect on flare's normal builds. - --sanitizer now rejects an invalid combo (e.g. address,thread) at the command line instead of mid-build after the load/analyze pass and build-dir creation. - Robustness: blade no longer crashes when git/svn is absent in a versioned workspace (SCM info degrades to 'unknown'). - MSVC C/C++ test coverage + coverage_config(exclude=...) (Windows-only; N/A to flare's Linux/macOS builds). No flare BUILD/source changes needed; verified flare builds clean on the new blade (base/encoding, a cc_test) and that --sanitizer=address still builds while address,thread is rejected instantly. |
||
|
|
83acfc7bf9 |
macOS: portable fiber stack under ASan + bump vendored blade (#202)
Two changes that together make `blade build/test --sanitizer / --coverage` work
on macOS:
- fiber: `GetMasterFiberStack()` used `pthread_getattr_np` (Linux/glibc only),
which fails to compile on macOS clang under ASan (`FLARE_INTERNAL_USE_ASAN`).
Add a macOS branch using `pthread_get_stackaddr_np` / `pthread_get_stacksize_np`
(the stack grows down, so bottom = stackaddr - stacksize).
- thirdparty/blade: bump the vendored blade (blade.zip + GITVERSION) to
blade-build 3488316, which includes the build-dir naming modernization, the
fixes that stop `cc_check_undefined` from flagging the coverage/sanitizer
runtime symbols (`__llvm_gcda_*`, `__ubsan_*`, the TSan `Annotate*` dynamic
annotations, ...), and the --gprof/--coverage platform gating (no more dead
`-pg` warnings on macOS).
- .gitignore: the new blade default build dir is `build_<profile>[_<variant>]`;
ignore `/build_*/` (keeping the legacy `build{32,64}_*`).
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
|
||
|
|
92a08ae18b |
tracing: migrate opentracing-cpp → opentelemetry-cpp (API only) (#201)
* tracing: migrate opentracing-cpp -> opentelemetry-cpp (API only) opentracing-cpp is deprecated/superseded by OpenTelemetry. flare ships no real tracer -- it exposes a pluggable abstraction (TracingOpsProvider / QuickerSpan / TracingOps) over the tracing-API types, with providers plugged in by users. Re-base that abstraction on the opentelemetry-cpp **API** (header-only, v1.27.0) and drop opentracing-cpp from both build systems. Scope: API only -- no SDK/exporter, so no protobuf/grpc is pulled in and the deliberately-pinned (abseil-free) protobuf 3.21.12 stays intact. The abstraction and the opaque `bytes tracing_context` wire format are kept; only the types/bodies change. Source (flare/rpc/tracing/): - tracing_ops_provider.h: re-typed virtuals; new flare-owned SpanStartOptions (parent SpanContext + SpanKind + timestamps + start attrs) replacing opentracing::StartSpanOptions/ChildOf. Extract -> std::optional<SpanContext>. - tracing_ops.h/.cc: span_ is nostd::shared_ptr<trace::Span>; SetAttribute/ AddEvent/End; SpanContext is a value type; buffered ops keep flare's owning variant and convert to (non-owning) AttributeValue only at flush. - framework_tags.h -> constexpr std::string_view; string_view_interop.h -> ToStd/ToOtel (nostd<->std). Standard-tag table is a literal allowlist; span.kind moves from a tag to SpanStartOptions::kind. - Call sites rpc_channel.cc / normal_connection_handler.cc updated; rpc_meta.proto comment updated (wire field unchanged). - Tests/benchmark rewritten onto a recording fake otel::trace::Span (OTel's noop span can't be asserted on); integration test asserts span kind via the provider-recorded "span.kind" instead of an opentracing tag. Build: - blade: BLADE_ROOT vcpkg_config gains opentelemetry-cpp; thin wrapper //thirdparty/opentelemetry-cpp:api (refs opentelemetry_common -- the api component is header-only with no .a; that lib's include dir carries the api + absl headers). opentracing thirdparty dir removed. - bazel: deps.bzl http_archive for opentelemetry-cpp 1.27.0 + api-only bazel/opentelemetry-cpp.BUILD (header-only, bundled nostd -> no abseil); patch_cmds drop the archive's nested BUILDs so the api headers can be globbed. opentracing BUILD/patch + .bazelignore/.gitattributes entries removed. Verified: blade and bazel both build //flare/rpc/tracing/... and pass tracing_ops_test + integration_test. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * ci: bazelignore thirdparty/opentelemetry-cpp (blade BUILD) The repo-wide `bazel build ...` job parses every BUILD file; the blade thin wrapper thirdparty/opentelemetry-cpp/BUILD uses blade-only syntax (vcpkg#...:lib, visibility='PUBLIC'). Add it to .bazelignore (the opentracing entry was removed but its replacement wasn't added). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * tracing: clang-format (v15) the migrated files Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * chore: drop accidentally-committed .claude/ tooling files Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * doc(tracing): note provider ABI contract for OpenTelemetry nostd types The TracingOpsProvider interface uses OpenTelemetry API types (nostd::shared_ptr<Span>, nostd::string_view, AttributeValue) directly. The nostd:: backing is a compile-time choice (bundled / std via OPENTELEMETRY_STL_VERSION / abseil) and the three are mutually incompatible types, so a provider must be built with the same OpenTelemetry configuration as flare. flare leaves the default nostd in place. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * chore: gitignore .claude/ (Claude Code local tooling) Prevents accidentally re-committing .claude/settings*.json (cf. review comments on PR #201). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * tracing: address PR #201 review follow-ups (non-blocking) - forcibly_sampled now routes `flare.sampling_priority` through the provider's `SetFrameworkTag` translation (before `IsSampled`) instead of a raw `SetAttribute`, keeping the `flare.`-prefixed tag consistent with every other framework tag and letting providers honor the force-sample signal. Add `ext::kSamplingPriority`. - An empty log key (single-arg `AddTracingLog`) now materializes as the default event name "log" so backends that group/display by event name don't render a blank one; document the per-log-event mapping. - Guard `QuickerValue`'s reliance on P0608R3 (C++20) with a static_assert so a future standard downgrade can't silently bind `const char*` to bool. - Reset `DummySpan`'s inline-static tags/logs at the start of the recording test so assertions can't observe leftovers. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
0e384ab787 |
fiber tests: sync waitable_test exclusive to bazel; cap fiber count under sanitizers (#199) (#200)
Two small, independent test tweaks surfaced while triaging the fiber sanitizer gaps (#199): - waitable_test is marked `exclusive = True` in the blade BUILD but was missing `tags = ["exclusive"]` in BUILD.bazel. Sync them -- it's a heavy test that shouldn't run concurrently with others. - scheduling_group_test spins up `min(max_map_count/4, 131072)` fibers. Under ASan/TSan that's both very slow (well past the test timeout) and memory hungry. Cap it to 4096 when a sanitizer is active (via FLARE_INTERNAL_USE_ASAN / _TSAN); a smaller count still exercises the scheduling paths. Non-sanitized builds are unchanged (still 131072). Note: these don't make the heavy tests sanitizer-clean on their own -- both still hit the use-after-poison tracked in #199 (a separate, deeper issue in the ASan fiber-switch annotations). Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
8396477144 |
ci: add ASan/TSan fiber regression lane (#134, #196) (#198)
* ci: add ASan/TSan fiber regression lane (#134, #196) The fiber-switch sanitizer fixes (#134 ASan/TSan SEGV, #196 detect_stack_use_after_return) had no automated coverage -- flare's CI is blade-based and never built under sanitizers, so these bugs sat undetected. Add a Bazel + clang job that builds and runs a curated set of fiber tests under both `--config=asan` and `--config=tsan` (matrix). Also add a `tsan` config to .bazelrc (mirroring the existing `asan` one). Scope: a curated list of fiber tests that pass cleanly under both sanitizers, which is enough to catch any regression of the fiber-switch fixes. The full `//flare/fiber/...` is intentionally NOT used -- it has unrelated sanitizer problems out of scope here: curl fails to foreign_cc-build under -fsanitize; a few sync-primitive tests (scheduling_group/latch/waitable) have their own ASan/TSan failures; and some tests exceed even a raised timeout under TSan. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * ci: download bazelisk to a temp path (repo has a bazel/ dir) The install step did `curl -o bazel`, but flare tracks a `bazel/` directory, so curl failed with exit 23 (can't write over a directory) before any test ran. Download to $RUNNER_TEMP instead. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * ci: narrow sanitizer_fiber to a fast core set, tighten timeout The 15-test set was fine under ASan (~4 min) but pathologically slow under TSan on shared 2-4 core runners (the heavier sync-primitive tests). Narrow to a focused set that exercises fiber create/resume/switch -- enough to guard the switch fixes, since a broken switch crashes every fiber test on first resume. Drop --test_timeout to 300s so a straggler fails fast instead of stalling. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * ci: pin sanitizer_fiber to clang-17 (clang-18 TSan header clash) flare's annotation.h hand-declares __tsan_* interface symbols (mutex flags, fiber no_sync) that collide with clang-18's <sanitizer/tsan_interface.h> ('non-static declaration follows static declaration'), breaking the TSan build. That's a separate pre-existing issue; pin the lane to clang-17 (the toolchain the fiber-switch fixes were verified on) so the regression guard is green. clang-18 TSan-header compatibility tracked separately. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * ci: force clang-17 via bazel --repo_env (update-alternatives ignored) The previous attempt used update-alternatives to point /usr/bin/clang at clang-17, but bazel's autodetected toolchain still resolved clang-18 (/usr/lib/llvm-18/bin/clang) from the runner's PATH, so the TSan build kept hitting the clang-18 tsan_interface.h clash. Configure the toolchain compiler explicitly with --repo_env=CC=/usr/bin/clang-17 (and CXX), and drop --config=llvm (which forced the generic 'clang'). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * ci: make clang-17 install non-interactive (apt hang) A TSan-leg runner got stuck in the apt install step (the ASan leg's identical step passed) -- a needrestart/debconf interactive hang. Set DEBIAN_FRONTEND=noninteractive + NEEDRESTART_MODE=a, sudo -E, and --no-install-recommends so the install can't block. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * ci: use preinstalled clang-17, stop apt-installing it (apt hangs) Multiple runner instances hung in 'apt-get install clang-17'. ubuntu-24.04 ships clang 16/17/18 preinstalled, so locate clang-17 directly (probe /usr/bin/clang-17 and /usr/lib/llvm-17/bin/clang) and point bazel at it via --repo_env. No apt install -> no hang; if clang-17 were ever absent the step fails fast instead of stalling. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fiber/ci: build TSan via <sanitizer/tsan_interface.h>; use default clang in CI annotation.h hand-declared the __tsan_* symbols (fiber API, mutex API + flag constants, acquire/release). Those collide with compiler-rt's <sanitizer/tsan_interface.h> ("non-static declaration follows static declaration") whenever that header is in the translation unit under -fsanitize=thread, which broke the TSan build on the CI runners (both the default clang-18 and the runner's clang-17 hit it). It is NOT version-specific. Include the canonical header directly instead of redeclaring. FLARE_INTERNAL_ USE_TSAN is only defined under -fsanitize=thread, and any toolchain providing that flag ships this header (verified: clang-17, and gcc-13 which also defines __SANITIZE_THREAD__ and exposes the fiber/mutex API), so it's always available. With the build no longer tied to a clang version, drop the CI lane's clang-17 pinning (which needed an apt install that intermittently hung) and just use the runner's default clang via --config=llvm. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
88f15ec849 |
fiber: fix TSan SEGV on fiber switch by stripping func-entry/exit hooks (#134) (#197)
Under TSan with clang, `bazel test --config=tsan //flare/fiber:*` crashes on
the first fiber resume:
ThreadSanitizer: SEGV ... in __tsan_func_entry
<- FiberProc (first instruction of a freshly-started fiber)
Root cause (traced with gdb): TSan keeps a per-fiber "shadow stack" of call
frames; `__tsan_func_entry` pushes and `__tsan_func_exit` pops it.
`flare::internal::tsan::SwitchToFiber` calls `__tsan_switch_to_fiber`, which
makes the *target* fiber's shadow stack active. But that call sits inside an
instrumented function, so the function's own injected `__tsan_func_exit` runs
*after* the switch -- popping the just-activated, and for a brand-new fiber
empty, shadow stack. shadow_stack_pos underflows to base-8; the next
`__tsan_func_entry` (at FiberProc) writes below the mapped region and SEGVs.
Confirmed: `-fno-sanitize-thread-func-entry-exit` (which removes those hooks)
makes it pass. Crucially, plain `[[no_sanitize("thread")]]` does NOT fix it --
it disables the data-race read/write checks but keeps the func-entry/exit
hooks, so the underflow remains.
Fix: add `FLARE_INTERNAL_DISABLE_SANITIZER_INSTRUMENTATION`
(`[[clang::disable_sanitizer_instrumentation]]`, which strips ALL hooks
including func-entry/exit) and apply it to the functions that bracket a raw
context switch: the `SwitchToFiber` wrapper, `FiberEntity::Resume`,
`FiberEntity::ResumeOn`, and the `FiberProc` entry trampoline. This keeps full
TSan instrumentation (and call stacks in race reports) everywhere else, unlike
the global compile flag. GCC has no such attribute (only Clang), so the macro
expands to nothing there -- GCC builds are non-sanitized, and TSan-with-fibers
is a Clang-only configuration in practice.
Verified with clang-17 under `--config=tsan` on both x86_64 and aarch64:
future_test / fiber_test / timer_test / this_fiber_test all pass. ASan (#196)
and the normal non-sanitized build are unaffected.
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
|
||
|
|
ff5e9ad540 |
fiber: fix ASan SEGV on fiber switch by disabling detect_stack_use_after_return (#134) (#196)
Under ASan with clang, `bazel test --config=asan //flare/fiber:*` crashes on
the first fiber resume:
SEGV in flare::internal::asan::StartSwitchFiber (annotation.h)
<- FiberEntity::Resume() <- ResumeOn() <- FiberProc()
Root cause: ASan's `detect_stack_use_after_return` (on by default since
Clang 11) gives each function its own "fake stack". flare hand-switches
between pooled fiber stacks; ASan's fake-stack bookkeeping cannot be followed
across that manual switch, so `__sanitizer_start_switch_fiber` faults. This is
independent of CPU arch (reproduced on both x86_64 -- the original report --
and aarch64) and of fiber stack size.
Fix: default `detect_stack_use_after_return=0` for any binary that links the
fiber runtime, via `__asan_default_options()` in fiber_entity.cc (always in the
fiber lib's link closure, so it isn't dropped). The ASAN_OPTIONS environment
variable still overrides it, and every other ASan check stays enabled. Also set
it in `.bazelrc`'s `build:asan` test_env so it's explicit for `bazel test` and
survives a user-provided `__asan_default_options`.
Verified with clang-17: with the env unset, future_test / fiber_test /
timer_test / this_fiber_test all pass under `--config=asan`.
Note: this addresses the ASan half of #134 only. The TSan crash has a
different root cause (TSan shadow handling for switched fiber stacks, not a
config toggle) and remains open.
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
|
||
|
|
3c103bd249 |
bazel/blade: drop hardcoded well_known_protos; auto-discover from vcpkg protobuf (#195)
blade-build#1339 (merged) makes blade auto-discover the well-known protos (google/protobuf/*.proto) from the protobuf include tree when proto_library_config.well_known_protos is empty. With the vcpkg#protobuf provider that resolves to the installed include/, so the list need not be hand-maintained in BLADE_ROOT and stays correct across protobuf versions. Empty the list (blade falls back to a built-in canonical set if the include tree is ever unresolvable) and vendor the blade.zip built from the merged blade master. Verified: building flare/rpc/... still passes --direct_dependencies with the same 12 google/protobuf protos, now discovered. Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
8c396a89d3 |
ci(test): mark overload/streaming RPC tests exclusive (#193)
server_test (overload), proto_over_http_protocol_streaming_rpc_test and std_protocol_streaming_rpc_test stress the whole machine; under concurrent CI load they crash (SIGSEGV/SIGABRT) or time out nondeterministically though they pass in isolation. Mark them exclusive so blade runs them alone. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
5a0132028e |
docs(thirdparty): mark openssl/nghttp2/curl migrated; only jsoncpp left (#191)
The curl cluster (#190) moved openssl (->3.x), nghttp2 and curl to vcpkg, so they move from the blocked table to the migrated table. jsoncpp is the sole remaining #179 lib (0.x->1.x API change). Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
ed29968f5a |
thirdparty: migrate openssl/nghttp2/curl to vcpkg (#179 curl cluster) (#190)
* thirdparty: migrate openssl/nghttp2/curl to vcpkg (#179 curl cluster) vcpkg has no openssl 1.1.1, so this upgrades the cluster to 3.x and migrates all three off foreign builds. Consumers' //thirdparty/{openssl,nghttp2,curl} targets are unchanged (thin vcpkg wrappers). - openssl -> vcpkg 3.x. flare's crypto/init code adapted for 3.x: - flare/io/util/openssl.cc: gut the obsolete OpenSSL-1.0.x ceremony (SSL_library_init, ERR_load_*, ENGINE_*, CRYPTO_set_locking_callback / CRYPTO_num_locks). OpenSSL 1.1+ auto-initializes and is internally thread-safe, so both entry points are now empty no-ops. - flare/base/crypto/{md5,sha}: -Wno-deprecated-declarations -- the low-level MD5/SHA/HMAC APIs are deprecated in 3.x (provider/EVP migration) but still valid until 4.0, so suppress rather than rewrite to EVP. - nghttp2, curl -> vcpkg (API-stable version bumps). curl built with the openssl + http2 features; its macOS frameworks (SystemConfiguration/Security/ CoreFoundation/CoreServices) link via blade's new pkg-config -framework support. Wrapper declares the sibling vcpkg deps (openssl/nghttp2/zlib). - thirdparty/blade/blade.zip: rebuilt with that -framework support. - Drop the vendored tarballs and patches (openssl/curl/nghttp2, curl dyld patch). Verified: full `blade test flare/...` green on macOS (crypto/ssl/curl/cos all pass). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * thirdparty/openssl: drop redundant #dl/#pthread blade now auto-propagates libcrypto's pkg-config system libs (Libs.private: -ldl) via the #1322 mechanism, and flare links pthread globally on Linux (cc_config). So the wrapper's explicit #dl/#pthread are redundant. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * ci: checkout the pinned vcpkg baseline (not just fetch) Fetching only the baseline commit let 'git show <baseline>:versions/baseline.json' resolve the baseline version, but vcpkg reads the per-port versions/*.json from the working tree -- still the runner's stale HEAD. For ports whose baseline version is newer than that HEAD (openssl 3.6.3, nghttp2 1.69, curl 8.20) vcpkg errors 'no version database entry'. Checkout the baseline so the whole version DB / ports tree is consistent (matching local dev). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
5fb5dbbbf0 |
thirdparty/protobuf: fix proto_test gtest include after vcpkg migration (#189)
proto_test.cc included the old in-tree full path "thirdparty/googletest/gtest/gtest.h", which no longer resolves after gtest moved to vcpkg (#187) -- only gtest_prod.h remains in-tree; gtest headers now come from vcpkg as "gtest/gtest.h" via the cc_test's gtest_libs include path. ubuntu-24.04 caught it on a cold build64_release; macOS/22.04 passed on cached objects. Switch to the standard "gtest/gtest.h". Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
ee31d650b0 |
docs(thirdparty): update vcpkg migration status (#188)
- gtest is migrated (#187) -> move to the ✅ table; note *_main libs resolve under vcpkg's lib/manual-link/ and the UnitTest-registry singleton is handled by the now-default 'auto' linkage. - Reflect blade's new default linkage='auto' (cc_library-like): singletons get one shared instance with no per-port annotation; only non-default choices (benchmark 'static', link_all_symbols/include_prefix/cmake_options) are spelled out. Drop the explicit linkage='auto' from the gflags/glog/yaml-cpp/protobuf rows; correct the yaml-cpp note (the old "wrapper .dylib exports" story was wrong) and add the protobuf descriptor-pool-singleton rationale. - Record the confirmed non-migratable libs: opentracing-cpp (vcpkg 1.6.0's variant.hpp uses std::result_of, removed in C++20 — needs the foreign build's patches), and blake3/rapidxml (in-tree vendored, not foreign builds). No code/BUILD changes: ctemplate and opentracing were evaluated for vcpkg this round and confirmed unmigratable, so they stay foreign. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
158f72be83 |
thirdparty: migrate googletest to vcpkg; adopt blade default 'auto' linkage (#187)
- googletest: thin wrappers over vcpkg gtest (gtest/gtest_main/gmock/gmock_main, pinned 1.17.0); drop the vendored tarballs and generate_dynamic.patch. gtest's *_main libs come from vcpkg's lib/manual-link/ (resolved by the updated blade). - BLADE_ROOT: update blade.zip to the build with default 'auto' linkage + the manual-link fix. With 'auto' the default, the explicit linkage='auto' on protobuf/gflags/glog/yaml-cpp/gtest is now redundant and removed; only the non-default choices remain (benchmark -> 'static' as it has no shared build; link_all_symbols / include_prefix / cmake_options where needed). - BLADE_ROOT: drop the hardcoded vcpkg `root` path -- blade reads $VCPKG_ROOT, else finds vcpkg on PATH (portable; CI uses the runner's vcpkg). Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
a1678b2278 |
thirdparty: migrate benchmark to vcpkg (pinned 1.7.1) (#186)
Replace the vendored google/benchmark 1.5.3 foreign build with a thin
vcpkg wrapper. Consumers keep depending on //thirdparty/benchmark:{benchmark,
benchmark_main}; cc_config.benchmark_libs / benchmark_main_libs are unchanged.
Pinned to 1.7.1: 1.8.0 deprecated benchmark::DoNotOptimize(const T&), which
flare's *_benchmark.cc use heavily, and flare builds gcc with
-Werror=deprecated-declarations (clang/macOS doesn't trigger it). 1.7.1 is the
last series before that deprecation.
vcpkg ships benchmark at its native include/benchmark/ layout, so no
include_prefix is needed. Drops the vendored tarball and the
remove_unused_var.patch.
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
|
||
|
|
7b68301df9 |
thirdparty: migrate yaml-cpp to vcpkg (#185)
yaml-cpp 0.6.3 -> vcpkg 0.9.0. linkage=auto + link_all_symbols (whole-archive the static .a into the wrapper shared lib so it exports symbols -- the real cause of the convert_to_map "ABI" undefined). thirdparty-only. |
||
|
|
ff0449e6dd |
thirdparty: upgrade protobuf to vcpkg 3.21.12 (last abseil-free) (#184)
Migrate protobuf from vendored 3.4.1 to vcpkg 3.21.12 (last release before Abseil became mandatory). vcpkg protoc + libprotobuf; source fixes for the 3.4->3.21 API (cpp_helpers.h, duplicate ext registration, Status::ToString); remove the ~47MB vendored 3.4.1 tree. Both blade and bazel builds + proto/RPC tests pass; protobuf install is abseil-free. |
||
|
|
2bfd54cdea |
thirdparty/blade: update blade.zip — print progress without cursor control (#183)
Update vendored blade to master 168ce01 (blade-build#1334): print ninja status lines when the terminal has no cursor control (CI/pipe), keeping builds observable. Honors --quiet, keeps the completion summary. |
||
|
|
39a8af2b6e |
bazel: silence macOS "ignoring duplicate libraries" warnings (#182)
Gate flare-own -lpthread/-ldl out on macOS (no-ops in libSystem) via select(), and add a macOS-only -Wl,-no_warn_duplicate_libraries (target + host links, auto-applied via enable_platform_specific_config) for the residual -lpthread/-lm from external deps. build_on_macos duplicate-library warnings: 128 -> 0. Closes #181. |
||
|
|
55d97852f7 |
thirdparty: migrate fmt/gflags/glog/zlib/lz4/zstd/snappy/xxhash to vcpkg (#180)
Migrate eight third-party libraries (fmt, gflags, glog, zlib, lz4, zstd, snappy, xxhash) from in-tree foreign builds to vcpkg, via blade native vcpkg support. Bundles the matching blade.zip (proto import-root + vcpkg protoc + transitive Requires linking + textual_hdrs) and the CI/Bazel adjustments (pinned vcpkg baseline; xxhash externalized for Bazel). |
||
|
|
24ab46abc2 |
thirdparty/blade: upgrade blade core and rewrite launcher for macOS (#178)
Update the vendored blade.zip (git-lfs) to the current build and rewrite the `blade` wrapper to locate the core next to the script and run it with a suitable Python interpreter, adding macOS support alongside Linux. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
092eb31166 |
thirdparty/gtest: build both static and shared libs to fix empty test registries on macOS (#177)
On macOS shared-library builds, several `:main`-based tests (http_mock_test, cos_mock_test, hbase_channel_test) ran zero test cases and printed "This test program does NOT link in any test case", even though their sources define real TEST()s. Root cause: gtest was static-only. Release builds default to dynamic_link, but with no libgtest.dylib the dynamic label fell back to the static archive, which then got force_loaded (link_all_symbols) into every mock/main dylib. Each dylib ended up exporting its own copy of gtest's UnitTest registry singleton, so TEST() registration bound to one copy while RUN_ALL_TESTS() (in libmain.dylib) read another. Whether a test tripped this depended purely on dylib link order. Fix: ship a shared libgtest so the registry is a single process-wide instance. googletest's CMake keys solely off BUILD_SHARED_LIBS and emits either static or shared per configure, so a single pass can't produce both. Add an optional second configure+install pass to cmake_build (`shared_cmake_options`) and use it for googletest: the static pass keeps libgtest.a for static_link consumers, the shared pass adds libgtest.dylib for dynamic_link ones. No source patch, so nothing to re-port on the next gtest bump (the stale generate_dynamic.patch was written for 1.10 and no longer applies to 1.17). Verified: both .a and .dylib are produced; the three tests now link libgtest.dylib and pass (8/3/2); ordinary gtest_main tests still pass; full //flare/... build links clean. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
4c1e391d88 |
docs: code-verified fixes across remaining docs + fill protocol/{http,new}.md (#176)
* docs(flare): code-verified fixes across remaining docs + fill protocol/{http,new}.md
Surgical fixes verified against current source:
- fiber.md, logging.md: flare::Async → flare::fiber::Async (no such alias at top level)
- io.md: malformed link io/../../io/detail/watchdog.h → ../io/detail/watchdog.h
- intro-http.md: HttpResponse::Status_OK → HttpStatus::OK (enum lives in net/http/types.h)
- rpc-form.md: typo Mssage → Message
- testing.md: stale namespace comment flare::testing::detail → example
- option.md: SomeParer → SomeParser, XxxOption>...> → XxxOption<...>,
StringToJsonParser → JsonParser (real name in base/option/json_parser.h)
- coding-comparison.md: read.Read() → reader.Read() (variable mismatch)
- protocol/protocol-buffers.md: EnableCompression → SetCompressionAlgorithm
(server controller has only the latter); max_queueing_delay →
max_queueing_delay_ms; flag accept_request_raw_bytes as TODO (still
commented out in rpc_options.proto:60 and std_protocol.cc:198)
- protocol.md: typo 内置协义 → 内置协议
- README.md: index orphans buffer.md / coding-comparison.md / gdb-plugin.md
added so they show up in the docs ToC
Filled previously-empty stubs:
- protocol/http.md: describes HTTP-as-wire-protocol entry points
(Http11Protocol, HttpService, HttpRequest/Response, HttpStatus) and
delegates user-facing usage to intro-http.md
- protocol/new.md: step-by-step guide for adding a new protocol —
StreamProtocol / Message / Controller / StreamService surfaces,
FLARE_RPC_REGISTER_*_STREAM_PROTOCOL* registration macros, and a
reference table of existing implementations (StdProtocol, Http11Protocol,
HbaseClient/ServerProtocol, RedisProtocol)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* docs: fix two dead links surfaced by markdown-link-check
- logging.md: CnTransGroup/EffectiveModernCppChinese was deleted upstream
(HTTP 404 on the repo itself). Drop the dead URL but keep the textual
reference to "Effective Modern C++" Item 30.
- protocol/protocol-buffers.md:249: relative path was missing the
"protocol/" segment — ../../rpc/protobuf/rpc_meta.proto →
../../rpc/protocol/protobuf/rpc_meta.proto (matches the three other
correct refs in the same file).
Both links pre-existed; the modified-files-only link checker only
surfaced them because this PR touched those two files.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
|
||
|
|
7fb4c8f0d8 |
docs(flare): verify and fix small issues across doc/ (#175)
* docs(flare): verify and fix small issues across docs/ Pure-mechanical cleanup pass through the remaining flare/doc/ files. Every change is verified against the actual code referenced. * `profiler.md`: title typo ``Profiller -> Profiler``; ``flag::Server`` -> ``flare::Server`` in the CPU profiler section. * `async.md`: ``Futrue`` typo -> ``Future``; link ``Async`` to its real header ``flare/fiber/async.h`` instead of leaving it as bare text. * `controller.md`: replace "see source code comments" with concrete header links (``rpc_client_controller.h``, ``rpc_server_controller.h``, ``rpc_controller.h``); link the "tracing" reference to ``tracing.md``. * `scheduling-group.md`: replace the ``...`` placeholder in the per-scheduling-group resources list with two concrete entries that exist in the code (object pool's ``memory_node_shared`` bucketing per NUMA node, monitoring's local-accumulate + cross-group aggregate reporting). * `gflags.md` / `buffer.md`: add the missing ``[返回目录]`` footer that every other doc has. ``buffer.md`` also had a stray triple ``)))`` in the last code sample -- removed. * `performance-guide.md`: fix broken header path ``../base/spinlock.h`` -> ``../base/thread/spinlock.h``. The file was moved into the ``thread/`` subdirectory at some point and the doc never followed. * `rpc-log-and-dry-run.md`: fix two weird relative paths that contained nested ``../`` segments and a literal ``binlog/`` prefix that doesn't exist (``binlog/../../rpc/binlog/dumper.h`` -> ``../rpc/binlog/dumper.h``, ``../binlog/../rpc/binlog/dry_runner.h`` -> ``../rpc/binlog/dry_runner.h``). No content rewrites; only typos, broken refs, and missing footers. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * docs(controller) + ci(link-check): fix #175 CI failures Two issues link-check surfaced on this PR: * controller.md referenced a non-existent ``flare/rpc/rpc_controller.h``. Actual hierarchy: ``RpcClientController`` and ``RpcServerController`` both inherit from ``protobuf::RpcControllerCommon`` (no shared ``RpcController`` header). Replace the wrong link with a plain text mention of the common base class. * performance-guide.md links to cppreference / stackoverflow / linux.die.net all 403'd against the link-check user agent. These URLs aren't broken in any normal browser; the docs were untouched in this PR but ``check-modified-files-only=yes`` re-scanned the file. Add the three domains to ``ignorePatterns`` with comments documenting the reason. The existing pattern for bazel.build set the precedent. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * ci(link-check): add dev.mysql.com to UA-filter ignore list Same shape as cppreference / stackoverflow / linux.die.net: the docs URL returns 403 to the action's User-Agent but works in any browser. Surfaced by rpc-log-and-dry-run.md re-scanning under this PR's edits. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com> |
||
|
|
d8d40cf461 |
docs(flare): fill in nslb.md, timer.md; refresh timestamp.md (#174)
* docs(flare): fill in nslb.md, timer.md; refresh timestamp.md for current impl
Three docs got attention:
* `nslb.md` was a 4-line stub. Filled in with the Channel -> NameResolver
+ LoadBalancer / MessageDispatcher data flow, registry mechanism for
custom name schemes, the two built-in load balancers (RoundRobin /
ConsistentHash), and the MessageDispatcher-integrated path for
routing services that bundle resolution + balancing (CL5, Polaris, ...).
* `timer.md` was also a 4-line stub. Covers the fiber-side API
(`SetTimer` / `KillTimer` / `SetDetachedTimer`, the `[[nodiscard]]`
contract), the `[this_fiber::SleepFor]` blocking-wait pattern, the
TimeKeeper for framework-internal periodic work, the TimerWorker
heap-based implementation, scheduling-precision expectations, and
the fire-and-forget cancellation semantics.
* `timestamp.md` was rewritten to match the current implementation:
- `ReadSteadyClock` / `ReadSystemClock` no longer bypass libstdc++.
Section now reflects that they delegate to `std::chrono::*::now()`
directly and explains why the old hand-rolled `clock_gettime`
path was removed (clock-epoch mismatch on macOS broke
`TimerWorker::cv_.wait_until()`; the CentOS 6 / tlinux 1.2
self-built-GCC problem the old impl worked around is no longer
relevant on any modern toolchain).
- Coarse clock section still accurate; description reworked to
show the atomic-load read path more clearly.
- TSC section preserves the existing technical content but adds the
"invariant TSC is now de facto standard" caveat and ties the
`DurationFromTsc` overflow warning to the long-duration case
more visibly.
- Added a top-of-file simple selection guide table and a
decision-tree at the bottom -- this is the part most readers
actually need.
No code changes.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* ci(link-check): ignore intel.com PDF UA-filtering
Intel CDN's PDF endpoint UA-filters markdown-link-check to 403 even
though the documents are reachable from any browser. Without this
ignore, the link-check fails any PR that touches a doc referencing
the canonical Intel whitepaper -- which is what just happened on
#172's timestamp.md re-shape.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* docs(timestamp): use kib.kiev.ua mirror for Intel TSC whitepaper
Intel's CDN UA-filters the link checker to 403; the kib.kiev.ua x86
documentation mirror serves the same Intel doc 333159 without the
filter, so we can verify the link in CI without an ignore-pattern
escape hatch.
Reverts the ``^https?://www\.intel\.com/.*\.pdf`` ignore added in the
previous commit on this branch -- no longer needed.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
|
||
|
|
356df6bb30 |
ci: skip heavy workflows on markdown-only changes (#173)
Adds `paths-ignore: ['**/*.md']` to the push/pull_request triggers of: - build-and-test.yml (blade build + test, longest job at ~25 min) - bazel-build.yml (bazel build + test, second-longest at ~15 min) - clang-format-check.yml (only inspects C/C++/Protobuf sources) GitHub Actions skips the workflow only when *every* changed file matches the ignore pattern, so mixed PRs (e.g. a code fix that also touches a README) still get full coverage. Pure docs/README PRs -- like the README rewrite -- now only run markdown-link-check, which is what actually verifies them. Saves ~25 min of CI wall time per pure-docs PR. The markdown-link-check workflow keeps its unconstrained trigger; documentation correctness still gets verified end-to-end. Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com> |
||
|
|
362e00a180 |
docs(readme): update for C++20 + macOS support, retranslate zh/en (#172)
* docs(readme): update for C++20 + macOS support, retranslate zh/en Bring both READMEs in line with the project's current state: * C++ badge upgraded from a generic ``C++`` to ``C++20`` to match the actual standard the project compiles with (``-std=gnu++2a``). * Platform badge upgraded from ``linux`` to ``linux | macOS`` -- macOS port landed in #158, CI matrix in #167 onwards. * Features section: drop the historical ``C++11/14/17/2a`` mix in favor of just ``C++20`` (the standard is committed; the staged adoption is no longer informative for a new reader). * System Requirements section split into ``Linux`` and ``macOS`` subsections, each listing the supported kernel/OS and the minimum toolchain that ships ``std::atomic<T>::wait`` / ``notify_*``: - Linux: GCC 11+ (libstdc++ added the operations in 11.1, per P1135 -- exposed locally on flare/fiber/detail/scheduling_group after the futex path went away in #158). - macOS: 13 (Ventura) or later with Apple Clang from Xcode 14+ (its libc++ has the matching runtime symbols). Also calls out aarch64 / arm64 / x86_64 explicitly. * Retranslated the zh README to read more like native Chinese -- the previous version had several literal-translation-isms ("吸收先前服务 框架"... etc.). Cross-checked the en against the zh and rewrote several en sentences that drifted out of step over the years (badge alt text, "out of the box" phrasing, the third-party tarball blurb, etc.). Both files now describe the same project in the same shape. * Added a back-link from the en README to the zh one (was one-way before). * Updated the blade-build link from chen3feng/blade-build to blade-build/blade-build (org moved). * Fixed bazel/support/README.md link typo (was REAMD.md). No code changes. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * docs: fix two markdown-link-check failures surfaced by the README PR * Rename `bazel/support/REAMD.md` -> `bazel/support/README.md`. The file has carried the swapped-letter spelling since 2023; the previous README link pointed at the typo'd name, so it was working by accident. The README rewrite in this PR pointed at the canonical spelling and surfaced that the file on disk was wrong. * Add `.github/markdown-link-check-config.json` to suppress the spurious "Status: 0" failure for `https://bazel.build`. The site returns a valid 200 to a normal browser and to `curl`, but apparently UA-filters the markdown-link-check action -- the action reads Status 0 and counts it as broken. Listed it in `ignorePatterns`; wired the config into the existing `gaurav-nelson/github-action-markdown-link-check@v1` invocation via the documented `config-file` input. Also bumps `retryOn429` (small reliability win when the action hits rate limits) and pins the success set to 200/206. Both surfaced by CI on this PR; no other changes. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com> |
||
|
|
d3bda1c595 |
thirdparty: route foreign_cc include dirs through -isystem (#171)
Two coupled changes: 1. Bump thirdparty/blade.zip from 9306687 to 5b305b0, picking up blade-build#1247 which adds the system_export_incs / system_include plumbing. 2. Switch foreign_build.bld's autotools_build and cmake_build gen_rules from ``export_incs=`` to ``system_export_incs=`` for the install include directory. Consumers now compile with ``-isystem<install_dir>/include`` instead of ``-I<install_dir>/include``, so diagnostics raised inside vendored third-party headers (glog self-deprecation, openssl pedantic notes, etc.) are no longer promoted to errors by our ``-Werror`` build. 3. Drop thirdparty/glog/silence_self_deprecation.patch + its entry in glog/BUILD's patches list. The patch was added in #168 to work around gcc-10's lack of the deprecated-inside-deprecated heuristic (every TU pulling in <glog/logging.h> hit the warning); the matrix moved to gcc-11 in #169 (where the heuristic suppresses it anyway), and -isystem now suppresses it generally on all toolchains. Two layers of belt + suspenders -> just the belt. Verified locally on macOS: a full ``./blade build ...`` (2118 actions) succeeds; emitted compile lines have ``-isystem<path>`` for every thirdparty include dir and unchanged ``-I<path>`` for flare's own export_incs. Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com> |
||
|
|
154c68adcc |
thirdparty/foreign_build: source cmake's CC/CXX from the resolved toolchain (#170)
* thirdparty/foreign_build: source cmake's CC/CXX from the resolved toolchain
cmake_build hard-coded ``CC=gcc CXX=g++`` for every cmake subbuild
(glog, jsoncpp, fmt, etc.), so the thirdparty layer always invoked
the distro-default compiler regardless of what blade had picked at
config time.
This was previously masked because:
1. flare's BLADE_ROOT doesn't declare a cc_toolchain_config, so blade
falls back to shutil.which('gcc') -- on a stock ubuntu_22 runner
that's gcc-11 (the distro default), which happens to match what
the cmake subbuilds were also hardcoding.
2. flare's CI workflow used to pass ``CC=gcc-10 CXX=g++-10`` as a shell
env prefix; blade itself ignores it (no env handling), but the cmake
subbuild *did* see it -- through the shell, not the hardcoded
prefix. So foreign_cc and flare-side disagreed but only on a
compiler version no longer in the matrix after #168.
After #168 + #169 the gap is benign for now (everything is gcc-11 or
clang anyway), but the hardcoded values would silently desync the
moment anyone:
- adds a cc_toolchain_config(name='ci', cc='gcc-13', ...) to BLADE_ROOT
and runs ``./blade --cc-toolchain=ci`` -- flare libs build with
gcc-13, glog/fmt/jsoncpp etc. build with gcc-11
- pins a non-default compiler via blade.getenv('CC', 'gcc')
- ports flare to a system where 'gcc' is not the desired compiler
Read CC/CXX from blade.cc_toolchain.tool() at config time. The proxy
returns the full path of whatever blade resolved (cc_toolchain_config
> shutil.which('gcc')). Verified locally: a forced glog rebuild now
emits ``CXX=/usr/bin/g++ CC=/usr/bin/gcc`` (the full resolved path)
instead of the bare names. Behaviour on the current CI matrix is
unchanged; the divergence is just no longer possible.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* thirdparty/foreign_build: also pass toolchain CC/CXX to autotools configure
Mirror of the previous commit for the autotools path. Without this,
configure pulls CC/CXX from $CC/$CXX in the environment (which blade
itself doesn't set) or falls back to its own autoconf detection --
both of which can disagree with whatever blade.cc_toolchain.tool()
resolved at config time. Setting CC/CXX on the configure command line
puts the thirdparty layer in lockstep with the rest of the build,
matching the cmake fix.
Verified on macOS local: a forced curl rebuild succeeds and the
emitted configure rule now contains ``CC=/usr/bin/gcc CXX=/usr/bin/g++``
(the full resolved path), rather than relying on environment leakage.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
|
||
|
|
802aa0b0b3 |
ci(test): tighten per-test timeout via --test-timeout-multiplier (#169)
* ci(test): tighten per-test timeout via blade --test-timeout-multiplier Three coupled changes: 1. **Bump thirdparty/blade.zip** from a76de22 to 9306687, picking up three new blade features merged today: - #1241 live test output streamed to <run_dir>/blade-test.log - #1244 blade.getenv() for opt-in env-driven config (config phase) - #1246 --test-timeout-multiplier CLI flag (run-time test-timeout scaling) 2. **Lower global_config.test_timeout from 600s to 60s.** The old 600s was a "fits all environments" compromise that meant a hung fast unit test took 10+ minutes to fail (witness: dumper_integration_test recently stuck 60+ min on a flaky ubuntu_22 runner). Profiling on M2 release/-O2 shows the slowest legitimate tests today are CPU-heavy ones around 30-40s -- and those are all already exclusive=True so they don't contend with the parallel pool. 60s gives ~50% headroom over the slowest legit case; anything blowing past it is almost certainly hung and worth failing fast. 3. **Scale up via --test-timeout-multiplier=5 in CI.** GHA runners are slower and contended; 5x = 300s effective ceiling. Tight enough that a real hang fails inside the GH step timeout (~6 hours), loose enough to absorb routine CI variance. Net effect: dev-machine timeouts catch hangs in 60s, CI absorbs runner slowness, and the cap-on-slowness lives in the CI workflow (where it belongs -- it's a property of the runner) rather than in BLADE_ROOT (which describes the project's intrinsic test cost). Verified locally: ./blade test ... --full-test passes all 235 tests under the 60s baseline. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * fix(build): drop unconditional -lpthread from gtest_libs on macOS Every cc_test that pulled gtest got '-lpthread' appended to the link line regardless of platform. On macOS Apple's ld then warns: ld: warning: ignoring duplicate libraries: '-lpthread' (pthread is part of libSystem and auto-linked; the explicit -lpthread is redundant and triggers the duplicate-library diagnostic on the new Xcode 16 linker). Wrap gtest_libs in a lambda that adds '#pthread' only when targeting Linux, matching the pattern already used for chrono / time_keeper / thread_pool and the thirdparty glog/gflags/etc. cc_test entries. Verified locally: every cc_test ninja file regenerated after this change has '-lpthread' gone on macOS; nothing changes on Linux (blade.cc_toolchain.target_os == 'linux' branch still emits it). Note: -lrt warnings observed in CI still appear, but those come from foreign_cc subbuilds (jemalloc / lz4 configure scripts) honoring the host environment via autoconf detection; they're internal to those packages, not from flare's link lines. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * fix(build): guard unconditional '-ldl' / '-lm' with Linux check Three places listed POSIX libraries as deps without a target_os check: - flare/base/internal:cpu -> '#dl' (uses dlsym for symbol lookup) - flare/base/internal:curl -> '#dl' (curl bindings) - thirdparty/openssl:crypto -> '#dl' (openssl needs dlopen at runtime) - thirdparty/protobuf-3.4.1 -> '#m' (math symbols) On macOS these symbols all live in libSystem and are auto-linked; the explicit '-ldl' / '-lm' is redundant. They don't typically trigger ld's "ignoring duplicate libraries" warning the way unconditional '#pthread' in BLADE_ROOT.gtest_libs did (since the .tbd stubs are designed for this redundancy), but the inconsistency was confusing and a single "-l<x>" arriving from two places anywhere downstream would tip into a real duplicate warning. Wrap each in the existing `target_os == 'linux'` / `_is_linux` pattern used elsewhere in the file. macOS link lines no longer contain '-ldl'/'-lm'; Linux is unchanged. Note: gperftools' BUILD still has unconditional '#pthread'/'#rt', but gperftools is excluded on darwin entirely (the macOS port routes through jemalloc instead), so those don't matter on macOS. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com> |
||
|
|
ed1e854280 |
ci: bump oldest-supported gcc to 11; make matrix.cc actually pick the matrix version (#168)
* ci: make matrix.cc actually pick the matrix gcc version
The Build and Test workflow's matrix promises gcc-10 on ubuntu_22 and
gcc-13 on ubuntu_24, but until now both jobs were actually compiling
with the distro default (gcc-11 / gcc-13) for the bulk of the build.
Cause: ``apt-get install gcc-10`` only installs the versioned binaries
(``/usr/bin/gcc-10`` etc.); ``/usr/bin/gcc`` keeps pointing at the
system default. Blade resolves the compiler via ``shutil.which('gcc')``
and reads no environment variable, so the ``CC=gcc-10 CXX=g++-10`` env
prefix on the Build step was decorative for the main build. Only
thirdparty foreign_cc subbuilds, which read $CC, actually saw gcc-10.
Effect on ubuntu_22 (the more important case -- gcc-10 is the
oldest-supported compiler the matrix claims to cover): the matrix
labelled "gcc-10" was silently testing gcc-11 for everything blade
compiled directly. Real gcc-10 compatibility was not under test.
Fix: register the matrix version with update-alternatives in Install
dependencies. After this, ``which gcc`` resolves to the matrix
version; both blade's compiler discovery and ccache's dispatch see
the right one. Drop the decorative ``CC=...`` prefixes from the Build
and Run tests steps now that they are no longer load-bearing (and
would have been misleading to future readers).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* thirdparty/glog: patch self-referencing deprecated overload for gcc-10
PR #168 switched ubuntu_22_04 from the distro-default gcc-11 (which the
prior workflow was silently using) to the actually-promised gcc-10. That
flipped the lid on a long-standing latent issue in glog 0.7.1:
glog/logging.h:494-505 declares a [[deprecated]] type alias
`CustomPrefixCallback` inside a `#pragma GCC diagnostic
push/ignored "-Wdeprecated-declarations"` block, then closes the
pragma block, then declares a [[deprecated]] overload of
`InitGoogleLogging` whose parameter type is `CustomPrefixCallback`.
gcc 11+ has a heuristic that suppresses deprecation warnings inside a
deprecated declaration's signature, so the overload's self-reference
stays silent. gcc 10 lacks that heuristic and fires
`-Werror=deprecated-declarations` on every TU pulling in <glog/logging.h>.
Patch (silence_self_deprecation.patch) moves the overload inside the
existing pragma block. No behavior change for callers; only the
internal self-reference stops warning. macOS clang and gcc 13 are
unaffected -- the diagnostic-suppression region simply covers slightly
more code on those toolchains too.
Verified by dry-run + real apply against a fresh extraction of
glog-0.7.1.tar.gz; the patched header preserves the original semantics.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* ci: bump oldest-supported gcc from 10 to 11
PR #168 made the matrix actually pick gcc-${{ matrix.cc }} instead of the
distro default (which was silently gcc-11 on ubuntu_22). With gcc-10 truly
exercised, two real incompatibilities surfaced:
1. flare/fiber/detail/scheduling_group.cc uses std::atomic<int>::wait,
notify_one, notify_all (C++20 P1135). libstdc++ implements these
starting in 11.1 only; gcc-10's <atomic> has no such members. PR #158
introduced the dependency when it replaced the Linux-only futex(2)
path with the portable C++20 primitives to make the macOS port work.
2. Several .cc files reference POSIX `unlink` without
`#include <unistd.h>`. Newer libstdc++ stopped transitively pulling
unistd through other headers.
Both are gcc-10 blockers we don't want to walk back -- atomic wait is
materially better than the futex path (portable, no syscall asymmetry).
Bump the matrix to gcc-11 and update the comment.
gcc-11 is the ubuntu-22.04 default, so the update-alternatives plumbing
becomes a no-op for this version but stays in place to keep future bumps
straightforward.
Keep the glog self-deprecation patch -- on gcc-11+ it is a no-op (the
heuristic suppresses the warning anyway), but it shields a local gcc-10
attempt from breaking on glog before the user even gets to the real
flare-side incompatibilities.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
|
||
|
|
6df0c8d6c8 |
ci: use ccache to make incremental CI builds actually incremental (#167)
Background: PR #164 added actions/cache for build64_release/, but incremental builds still run nearly cold (~15-18 min on Linux, ~14 min on macOS) -- log shows ninja starts from [1/2956], not a partial. Root cause: actions/checkout sets all source mtimes to "now", which is newer than the cached .o files, so ninja decides everything has changed and recompiles. ccache fixes this with content-based hashing, ignoring mtime entirely. Hooked in via the PATH-injection mechanism that ccache was designed for: /usr/lib/ccache/{gcc,g++,gcc-10,...} -> ccache binary echo "/usr/lib/ccache" >> $GITHUB_PATH Blade resolves the compiler via shutil.which('gcc'), so prepending /usr/lib/ccache to PATH redirects to the ccache shim with no change to blade itself. ccache dispatches to the real compiler internally. The existing build64_release cache is kept -- ccache cannot cache thirdparty/foreign_cc subbuilds (autotools/cmake produce many compile + link invocations that ccache treats individually but the foreign_cc driver itself is the slow part). The two caches are complementary: build64_release -> thirdparty; ccache -> regular cc_library/cc_test. Expected effect on incremental PRs (master cache hits): Build step on Linux: ~15 min -> ~3-5 min (only changed .cc recompile) Build step on macOS: ~14 min -> ~3-5 min Cold cache (e.g. thirdparty bump): no regression The "ccache stats" steps print hit/miss counts so we can watch the ratio over the first few PRs and tune if needed. Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com> |
||
|
|
f2da35a126 |
test: mark CPU-heavy tests exclusive for scheduling stability (#166)
Local profiling on M2 (release/-O2) shows these tests each consume 3+ effective cores when run standalone: memory_node_shared_test 811% CPU dpc_test 576% CPU monitoring_test 554% CPU waitable_test 331% CPU hazptr_test 321% CPU When run inside blade's parallel pool, they over-subscribe the box and starve other tests for CPU. The primary harm isn't wall time -- it's *stability*: timing-sensitive tests neighboring these get non-deterministic latency, leading to CI flakes that don't reproduce locally. Mark all five exclusive (same scheduler queue as the existing exclusive tests: chrono_test / time_keeper_test / timer_test / this_fiber_test / scheduling_group_test / dumper_test, which are exclusive for the same reason -- timing accuracy under contention). Local wall: +106s (2m44 -> 4m30) on 8-core M2 where pool is already CPU-saturated. CI runners (2-core GHA) likely see smaller regression -- or improvement -- because the oversubscription pain was worse there. We'll measure on the actual CI workflow and re-tune the threshold (currently CPU% > 300) if needed. Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com> |
||
|
|
8a156b686e |
ci: cache bazel output + blade build64_release across runs (#164)
Both bazel and blade CI workflows currently start from scratch on every push. Big wastes: foreign_cc thirdparty libs (curl/openssl/jemalloc/ nghttp2) each take minutes to build, and all .cc files always recompile even when the PR only touches a few of them. Add ``actions/cache@v4`` to both: * ``bazel-build.yml``: cache ~/.cache/bazel (the output base; covers external repos, all build artifacts, and test result cache). * ``build-and-test.yml``: cache build64_release. Key per (OS, gcc) since binaries aren't portable across either. Cache key for both is hashed over WORKSPACE / BUILD files / thirdparty source tarballs so any structural change invalidates. restore-keys falls back to the most recent same-OS cache on miss so non-master branches still benefit from master's cache. Estimated effect: full cold-cache build still ~24 min; subsequent incremental builds (most PRs) drop to ~5-10 min depending on which .cc files changed. README/doc-only PRs become near-instant. Caveats: * GHA cache is capped at 10 GB/repo; older keys evicted LRU. With 3-4 OS x compiler combinations and bazel + blade entries we may push that ceiling -- watch for thrash. * PRs only read the base-branch (master) cache; cross-PR sharing doesn't happen. Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com> |
||
|
|
af2e463e31 |
test: shrink over-scaled loops in run_queue / waitable / fiber tests (#165)
* test(run_queue): shrink 3 over-scaled Torture/Overrun/Throughput cases Local arm64 run of run_queue_test split by case: Basics / Steal / Nonstealable: 0 ms each Torture 9'906 ms -> 402 ms Overrun 66'679 ms -> 4'152 ms Throughput 5'298 ms -> 327 ms total 81'883 ms -> 5'448 ms (15x) All three were stress tests with iteration counts well beyond what the assertions need: * Torture: N=1M items / T=200 threads / k=10 outer => N=200K / T=100 / k=3 (still 60M operations -- plenty to exercise the ring buffer) * Overrun: N=100K / T=40 / k=10 => N=20K / T=20 / k=3 (still hammers the queue's overrun-handling path repeatedly) * Throughput: N=1M / T=200 / k=10 => N=200K / T=100 / k=3 (still measures real throughput) Same pattern as #163: keep the test's intent, drop the over-budget loop sizes. Largest single-test win identified after that PR landed. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * test(waitable, fiber): shrink more over-scaled loops After run_queue_test (above commit), next-biggest single-test offenders on local arm64 (release/-O2) were: waitable_test 43.7s fiber_test 13.9s waitable_test (24 parameterized cases): ConditionVariable N=10000, outer=10 -> N=2000, outer=3 ConditionVariable2 N=1000, outer=50 -> N=1000, outer=10 ExitBarrier N=10000, outer=10 -> N=2000, outer=3 Event N=10000, outer=10 -> N=2000, outer=3 OneshotTimedEventTorture N=10000, outer=10 -> N=2000, outer=3 (rest leave alone -- already small) Result: 43.7s -> 24.1s fiber_test::SchedulingGroupLocal had a hardcoded ``while (start + 10s > ...)`` busy-wait. Comment said "10s should be far from enough" (intentionally generous; the assertion under test fires immediately if the bug is present). Reducing to 3s preserves both intent and the assertion's safety margin. Result: 13.9s -> 7.5s Combined wall savings on flare's CI: ~30s after 10-way test parallelism. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com> |
||
|
|
d5e44603db |
test: shrink over-scaled loops + exclude *_benchmark from bazel CI
Six commits' worth of test-step CI wall-time reduction.
* Loop reductions in five tests that were stress-testing far harder than
their assertions required. Local arm64 fastbuild measurements:
semaphore_test 115.6s -> 1.1s (105x; cut 1M threads to 10K)
id_alloc_test 50.7s -> 0.9s (56x; cut 1B allocs to 10M)
hash_map_test 42.0s -> 1.8s (23x; cut 5M iter to 500K)
timer_worker_test 31.0s -> 5.8s (5x; cut 4M ops to 100K)
writing_buffer_list_test 22.0s -> 4.5s (5x; cut Torture configs)
* Tag *_benchmark cc_test with tags = ["benchmark"] and exclude from CI
via --test_tag_filters=-benchmark. 30 BUILD.bazel targets tagged.
Bazel CI was running 30 benchmark cc_test targets including
hash_map_benchmark (86s), case_insensitive_hash_map_benchmark (70s),
dpc_benchmark (54s). Matches blade's semantics where cc_benchmark is
a cc_binary (not picked up by ./blade test).
Estimated CI wall savings ~3 min on bazel job. All reduced tests still
exercise the same race / overflow / stress patterns -- just at sensible
iteration counts.
|
||
|
|
51cf5a5587 |
ci: unflake timing tests + bump deprecated actions + blade.zip (3 fixes)
Three CI hygiene fixes bundled in one PR.
* **Flaky timing assertions widened**. Two tests had ASSERT_NEAR / EXPECT_NEAR
with budgets too tight for shared-VM CI runners:
- flare/net/http/binlog_dry_runner_integration_test:220 -- 20ms -> 50ms
(observed 136ms vs expected 100ms on GHA).
- flare/io/native/stream_connection_test:411 and :491 (WriteBandwidthLimit
/ ReadBandwidthLimit) -- 1s -> 2s (observed 8.4s vs expected 7s).
Both tests still validate order-of-magnitude correctness; just give
shared-runner jitter the headroom it needs.
* **Deprecated GitHub Actions bumped** to silence the "Node.js 20 actions
are deprecated" warning (forced upgrade scheduled for Sept 2026):
- actions/checkout: @v2 / @v3 / @master -> @v6 (Node 24)
- actions/setup-python: @v2 -> @v6
* **thirdparty/blade: bump blade.zip to master a76de22**. Picks up three
upstream blade-build fixes that surfaced after master a8d12b2 wired in
the new cc_check_undefined static check:
- #1238: add __tls_get_addr / __tls_get_offset to undefined-check
baseline (ld-linux.so injects these); unbreak stale CheckUndefinedDiff
unit tests; defer PrebuiltCcLibrary._emit_archive_syms to generate
phase (was tripping the __build_code-None invariant in
Target.before_generate).
- #1239: treat uppercase 'V' / 'W' nm symbol types as defined, not
ambient -- they're weak DEFINED, not weak UNDEFINED.
- #1240: treat lowercase 'u' as defined (GNU "unique global"
extension) -- fmt's basic_data<void>::*_padding_shifts and ~40 other
template-static-data symbols were silently dropped from libfmt.a's
syms set, breaking any cc_library that transitively used fmt.
|
||
|
|
8cc6c17c63 |
thirdparty/blade: bump blade.zip to current master (a8d12b2) (#161)
The vendored blade in `thirdparty/blade/blade.zip` was at commit 82ba580 (the export_map → -exported_symbols_list change), which predates the dep-check improvements merged later the same day: 82ba580 ← bundled here previously 9a0138e Cache ToolChain.get_cc_target_arch (#1224) 6db819c incchk: cut false positives in unused-deps + docs (#1231) 7f182fa feat(cc): decouple undefined-symbol checking (#1225) (#1233) e4e0c8b docs(cc): document static undefined-symbol check (#1234) a8d12b2 docs(cc): two more missing-dep cases + log demote (#1237) ← now bundled User-visible change: `./blade build flare/...` now reports the same dependency notices that the upstream master blade does. With the older bundle, a full `flare/...` build surfaced 62 Unused-dep notices that the four auto-exemption rules introduced in #1231 already handle (header re-export across umbrella + sub-target, export_incs- relative paths, foreign_cc_library header-less auto-exempt, no- scannable-source skip). Re-bumping clears them without any BUILD edits. Numbers on macOS arm64, -j10, full `./blade build flare/...`: Notice category Before bump After bump ---------------- ----------- ---------- Missing-dep 0 0 Unused-dep 62 0 Build success yes (no functional change) |
||
|
|
6a159d839b |
Resolve the two long-standing Missing-dependency notices (#160)
`blade build --cc-check-undefined flare/...` has been emitting two Missing-dep notices since PR #159 went in -- they were known and intentionally left at the time as "visibility-blocked" cases. With a follow-up look they turn out to be two distinct patterns, each fixable without exposing internals: * `flare/base:exposed_var_test` -- `flare/base/write_mostly/metrics.h` was a dead include. The test only uses `ExposedMetrics<T>` (defined in `flare/base/exposed_var.h`, already included); it never names any symbol from `metrics.h`. blade was correctly reporting the include; the right fix is to delete the include, not add a dep on `:write_mostly` (private encapsulation preserved). * `flare/rpc:rpc` -- `flare/rpc/http_filter.h` / `http_handler.h` (rpc:rpc's own public hdrs) re-`#include` `protocol/http/http_filter.h` / `http_handler.h` so consumers of the outer facade see the types. `:http_filter` / `:http_handler` had `visibility = '//flare/rpc:http'`, which blocked rpc:rpc from depending on them even though it's exactly the canonical re-exporter. Widen the visibility narrowly to also allow `//flare/rpc:rpc` (C++ `friend`-style allow-list -- still not PUBLIC, still locked down to the two known facade targets), then declare the deps explicitly on the umbrella's side. Both endpoints carry comments explaining the re-export relationship. After this: `blade build --cc-check-undefined flare/...` reports zero Missing-dep notices and zero Unused-dep notices. For the design rationale of both patterns, see the corresponding blade-build docs PR which adds them as cases 6 and 7 in "Fix missing dependencies errors caused by `hdrs`". |