Conversation
WalkthroughCopyBaseToArchive now stops per-item loop on a read-callback error, waits for in-flight reads to finish, then checks an aggregated error code and returns false if set. UpsertTable received non-functional formatting changes. SwitchReadOnlyToClosed sets Changes
Sequence Diagram(s)sequenceDiagram
participant Caller
participant Client as DataStoreServiceClient
participant Reader as PerItemRead
Caller->>Client: Request CopyBaseToArchive
Client->>Reader: enqueue per-item read (loop)
alt per-item read callback succeeds
Reader-->>Client: callback (success)
else per-item read callback reports error
Reader-->>Client: callback (error)
Client->>Client: break out of per-item loop
end
Client->>Client: wait for all in-flight reads to finish
Client->>Client: check aggregated error_code
alt error_code == 0
Client-->>Caller: return true / continue
else error_code != 0
Client-->>Caller: log error and return false
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes
Possibly related PRs
Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (1 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (1)
🧰 Additional context used🧬 Code graph analysis (1)data_store_service_client.cpp (1)
🔇 Additional comments (3)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
eloq_data_store_service/data_store_service.cpp (1)
2291-2297: Potential UAF: nullingdata_store_while reads may still be in flightAfter CAS to Closed, in-flight Read/Scan RPCs that already passed the status check can still hit
assert(data_store_ != nullptr); data_store_->.... Settingdata_store_ = nullptrhere risks a use‑after‑free. Writes are explicitly drained, but reads aren’t.Consider one of:
- Drain outstanding reads before destruction (add an
ongoing_read_requests_counter, increment in all read/scan entry points, and wait to zero here beforeShutdown()and null).- Protect
data_store_with a shared lock or usestd::shared_ptrand passweak_ptrto closures so late callers won’t dereference freed memory.- If you can’t drain now, keep the pointer non‑null post‑Shutdown and defer nulling to teardown where no RPCs run.
data_store_service_client.cpp (1)
2399-2411: Do not early-return before draining in-flight reads (UAF risk)The
return falseinside the scheduling loop can exit while many reads are still in flight;callback_datasthen go out of scope and callbacks may dereference freed memory.Replace early return with “stop scheduling, then drain all outstanding reads, then fail”:
- if (callback_data->GetErrorCode() != 0) - { - LOG(ERROR) - << "CopyBaseToArchive failed for read base table."; - return false; - } + if (callback_data->GetErrorCode() != 0) + { + LOG(ERROR) + << "CopyBaseToArchive read error detected; stop scheduling new reads and drain."; + // Stop scheduling further reads for this batch + // (break out of the base_vec loop; outstanding reads will still complete). + break; + }And after the drain (the “Wait the result all return” block), decide based on the aggregated error:
{ std::unique_lock<bthread::Mutex> lk(mtx); while (flying_cnt > 0) { cv.wait(lk); } } + if (error_code != 0) { + LOG(ERROR) << "CopyBaseToArchive failed for read base table."; + return false; + }This preserves safety while still failing fast post‑drain.
🧹 Nitpick comments (1)
data_store_service_client.cpp (1)
2425-2429: Post‑drain error check: good safeguardThis second‑stage check (after all reads have completed) is safe and fixes the “ignored read error” bug. If you adopt the “no early return” change above, you can also rely on the shared
error_codeto avoid per‑callback checks in this loop.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
data_store_service_client.cpp(1 hunks)eloq_data_store_service/data_store_service.cpp(1 hunks)
1. copybasetoarchive read err code is ignored 2. data store close didnot reset pointer to null
Summary by CodeRabbit