Repository navigation
Conversation
`HTTPConnectionInfoScope` pairs a `system.blob_storage_log` row with the connection that carried its request through `thread_local` state. A request made in a Silk fiber can resume on another thread in the middle of it, and the fibers that run on one scheduler thread interleave their scopes, so a row could get another request's connection or none. The state is now one `FiberLocal` object, like `TracingContextOnThread` (`src/Common/OpenTelemetryTraceContext.cpp`). Its slot is shared with the stackful coroutines of a thread, so threads and coroutines keep the previous behavior. Test: more fibers than scheduler threads each publish a connection inside their own scope and take it back after all of them have published.
|
Workflow [PR], commit [c711e8c] AI ReviewSummaryMoves the HTTP connection attribution state used by Missing context / blind spots
Findings❌ Blockers
Tests
Final Verdict❌ Block — make the regression test's barrier and fiber cleanup safe on exceptional exits, then verify the failure paths and normal concurrent-fiber case. |
| std::vector<silk::FiberFuture> futures(fiber_count); | ||
|
|
||
| size_t spawned = 0; | ||
| while (spawned < fiber_count && Silk::spawn([&, i = spawned] |
There was a problem hiding this comment.
[Blocker] Keep the shared test state alive when scheduling throws
Silk::spawn can throw: it calls FiberLocalStorage::create, which uses throwing new. If one spawn succeeds and a later one throws, execution skips both dropParticipants calls and the wait loop. silk::FiberFuture has no joining destructor, so futures, results, and both barriers are destroyed while successfully started fibers still reference them. This permits use-after-free or strands fibers at a barrier.
Please install an RAII cleanup guard after the shared locals that releases waiting participants and joins every successfully spawned fiber on exceptional exits too. Also account for a fiber failing before it reaches published: the new HTTPConnectionInfoScope can allocate and throw, and FiberContext::main returns EIO without dropping that participant, leaving the remaining fibers waiting indefinitely. A focused allocation-failure check after the first successful spawn should verify that these paths terminate safely.
mstetsyuk
left a comment
There was a problem hiding this comment.
LGTM, but each FiberLocal<...>::operator-> call is 4 extra instructions on ARM: get the underlying thread local storage base pointer, add the FiberLocalStorageThreadStorage + slot offset to that base, read the object pointer from the resulting pointer, check if it's null, dereference it. We can use FiberLocal<...>::get() once instead. Not sure if this place is hot enough, but IMO still worth doing as a simple optimisation, no complexity.
Build profile diff (arm_release)Comparing ✅ No significant changes. Binary sizes
The official master build is compiled with Slowest function optimization changes (ThinLTO)Median per-function time ratio to the master baseline:
Compile time of recompiled translation units1636 translation units recompiled, 10430 s compile time in total, 1636 of them have a recent master baseline. |
The connection info that pairs a
system.blob_storage_logrow with its HTTP connection is now kept per fiber instead of per thread, so requests made in Silk fibers log their own connection.HTTPConnectionInfoScopehands the connection of a blob storage request to the code that logs it throughthread_localstate. A request made in a Silk fiber can resume on another thread in the middle of it, and the fibers that run on one scheduler thread interleave their scopes, so a row could get another request's connection or none.FiberLocalobject, likeTracingContextOnThread(src/Common/OpenTelemetryTraceContext.cpp). Its slot is shared with the stackful coroutines of a thread, so threads and coroutines keep the previous behavior.thread_localhandoff now describes the fiber-local one.No caller in this repository makes blob storage requests from fibers yet. The new gtest runs more fibers than scheduler threads; each publishes a connection inside its own scope and takes it back after all of them have published, which fails with per-thread state.
Changelog category (leave one):
Workflow [PR]
Sync PR [sync-upstream/pr/131273]