feat: add lazy delete scheduling of txobject#480
Conversation
|
Warning Rate limit exceeded
You’ve run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
WalkthroughThis PR introduces a lazy-free deallocation mechanism for transaction objects. Commands can mark deletes as lazy-delete; during commit, lazy-deleted objects are enqueued for deferred freeing rather than immediately released, with periodic draining within time budgets. ChangesLazy-Free Object Deallocation Infrastructure
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Tip 💬 Introducing Slack Agent: The best way for teams to turn conversations into code.Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.
Built for teams:
One agent for your entire SDLC. Right inside Slack. 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: 1
🧹 Nitpick comments (1)
tx_service/include/tx_service.h (1)
411-411: 🏗️ Heavy liftPlease add focused coverage for lazy-free round processing.
Given this line changes scheduler accounting, add/extend tests to validate that lazy-free draining contributes to round progress and does not starve regular/low-priority processing under sustained lazy-delete load.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@tx_service/include/tx_service.h` at line 411, Add focused unit/integration tests that exercise lazy-free round processing so the change to req_cnt via local_cc_shards_.ProcessLazyFreeQueue(thd_id_) is covered: write a test that injects sustained lazy-delete workload into the shard(s), calls the scheduler loop (or the method that contains req_cnt increment logic) and asserts that req_cnt increases when ProcessLazyFreeQueue is invoked and that scheduler round counters/metrics advance; additionally add a contention test that runs concurrent low-priority/regular requests alongside continuous lazy-delete operations and asserts regular requests make forward progress (no starvation) and latency/throughput stay within thresholds. Target the tests at the components that own local_cc_shards_ and the scheduler loop so you validate both the req_cnt accounting and that ProcessLazyFreeQueue(thd_id_) does not starve normal processing.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@tx_service/include/cc/cc_shard.h`:
- Around line 455-457: lazy_free_queue_ is a std::vector accessed concurrently
by EnqueueLazyFree (multiple producers) and ProcessLazyFreeQueue (single
consumer) without synchronization, causing data races; fix by adding explicit
synchronization: protect all accesses and mutations of lazy_free_queue_ (e.g.,
push_back, pop_back, clear) with a mutex (e.g., lazy_free_mutex_) used by
EnqueueLazyFree and ProcessLazyFreeQueue, or alternatively change the API and
document/ enforce strict single-thread affinity so EnqueueLazyFree may only be
called from the shard's designated thread (update comments and any assertions in
EnqueueLazyFree/ProcessLazyFreeQueue); ensure the existing atomic counter
remains consistent with the guarded operations.
---
Nitpick comments:
In `@tx_service/include/tx_service.h`:
- Line 411: Add focused unit/integration tests that exercise lazy-free round
processing so the change to req_cnt via
local_cc_shards_.ProcessLazyFreeQueue(thd_id_) is covered: write a test that
injects sustained lazy-delete workload into the shard(s), calls the scheduler
loop (or the method that contains req_cnt increment logic) and asserts that
req_cnt increases when ProcessLazyFreeQueue is invoked and that scheduler round
counters/metrics advance; additionally add a contention test that runs
concurrent low-priority/regular requests alongside continuous lazy-delete
operations and asserts regular requests make forward progress (no starvation)
and latency/throughput stay within thresholds. Target the tests at the
components that own local_cc_shards_ and the scheduler loop so you validate both
the req_cnt accounting and that ProcessLazyFreeQueue(thd_id_) does not starve
normal processing.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 280c4a28-1a7d-4c94-982c-1c301ed5be1a
📒 Files selected for processing (6)
tx_service/include/cc/cc_shard.htx_service/include/cc/local_cc_shards.htx_service/include/cc/object_cc_map.htx_service/include/tx_command.htx_service/include/tx_service.htx_service/src/cc/cc_shard.cpp
| void EnqueueLazyFree(std::unique_ptr<TxObject> obj); | ||
|
|
||
| size_t ProcessLazyFreeQueue(); |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Verify implementation of lazy-free queue APIs and counter updates.
set -euo pipefail
echo "== Locate lazy-free API implementations =="
rg -n --type=cpp --type=cxx --type=cc --type=h \
'\bCcShard::EnqueueLazyFree\s*\(|\bCcShard::ProcessLazyFreeQueue\s*\('
echo
echo "== Inspect all lazy_free_queue_ and lazy_free_queue_size_ accesses with context =="
rg -n -C3 --type=cpp --type=cxx --type=cc --type=h \
'\blazy_free_queue_\b|\blazy_free_queue_size_\b'
echo
echo "== Check call sites for EnqueueLazyFree =="
rg -n -C2 --type=cpp --type=cxx --type=cc --type=h \
'\bEnqueueLazyFree\s*\('
echo
echo "== Check where ProcessLazyFreeQueue is invoked (run loop integration) =="
rg -n -C2 --type=cpp --type=cxx --type=cc --type=h \
'\bProcessLazyFreeQueue\s*\('Repository: eloqdata/tx_service
Length of output: 152
🏁 Script executed:
#!/bin/bash
# Corrected script without invalid --type=cxx
echo "== Locate lazy-free API implementations =="
rg -n --type=cpp --type=cc --type=h \
'CcShard::EnqueueLazyFree|CcShard::ProcessLazyFreeQueue'
echo
echo "== Find CcShard implementation files =="
fd -e cc -e cpp | head -20
echo
echo "== Search for lazy_free_queue_ member accesses =="
rg -n -C3 'lazy_free_queue_' --type=cpp --type=cc --type=h
echo
echo "== Search for lazy_free_queue_size_ member accesses =="
rg -n -C3 'lazy_free_queue_size_' --type=cpp --type=cc --type=hRepository: eloqdata/tx_service
Length of output: 1131
🏁 Script executed:
#!/bin/bash
# Search without type filters and find CcShard implementation
echo "== Find cc_shard header and implementation =="
find . -name "*cc_shard*" -type f | head -20
echo
echo "== Search for lazy_free_queue in entire repo (no type filter) =="
rg -n 'lazy_free_queue' | head -40
echo
echo "== Search for EnqueueLazyFree in entire repo =="
rg -n 'EnqueueLazyFree' | head -40
echo
echo "== Search for ProcessLazyFreeQueue in entire repo =="
rg -n 'ProcessLazyFreeQueue' | head -40Repository: eloqdata/tx_service
Length of output: 2279
🏁 Script executed:
#!/bin/bash
echo "== EnqueueLazyFree implementation (cc_shard.cpp:777) =="
sed -n '777,790p' tx_service/src/cc/cc_shard.cpp
echo
echo "== ProcessLazyFreeQueue implementation (cc_shard.cpp:789) =="
sed -n '789,820p' tx_service/src/cc/cc_shard.cpp
echo
echo "== Context around line 245-246 (clear/reset) =="
sed -n '240,250p' tx_service/src/cc/cc_shard.cpp
echo
echo "== EnqueueLazyFree call sites in object_cc_map.h (context) =="
sed -n '2848,2860p' tx_service/include/cc/object_cc_map.h
echo
sed -n '2882,2895p' tx_service/include/cc/object_cc_map.h
echo
echo "== Check CcShard class for thread affinity or mutex guards =="
rg -n 'shard_mutex|thread_id|mutex' tx_service/src/cc/cc_shard.cpp | head -20Repository: eloqdata/tx_service
Length of output: 2767
🏁 Script executed:
#!/bin/bash
echo "== Processor loop in tx_service.h:411 =="
sed -n '405,420p' tx_service/include/tx_service.h
echo
echo "== Check for thread pool or thread affinity design =="
rg -n 'thread_id|thd_id|Thread Affinity|single.thread' tx_service/include/cc/cc_shard.h | head -20
echo
echo "== Check CcShard constructor for any thread affinity setup =="
sed -n '1,100p' tx_service/src/cc/cc_shard.cpp | grep -A 30 'CcShard::CcShard'
echo
echo "== Check for any mutex or lock guards protecting lazy_free_queue =="
rg -n 'std::lock|std::unique_lock|std::scoped_lock|mutex.*lazy_free' tx_service/src/cc/cc_shard.cpp
echo
echo "== Check NotifyTxProcessor to understand synchronization =="
rg -n -A 10 'void.*NotifyTxProcessor' tx_service/src/cc/cc_shard.cppRepository: eloqdata/tx_service
Length of output: 2797
🏁 Script executed:
#!/bin/bash
echo "== Check object_cc_map.h class documentation =="
head -100 tx_service/include/cc/object_cc_map.h | grep -A 20 'class.*ObjectCcMap'
echo
echo "== Check Enqueue method documentation in cc_shard.h =="
sed -n '380,440p' tx_service/include/cc/cc_shard.h
echo
echo "== Look for thread safety documentation in cc_shard.h =="
rg -n 'Thread.safe|thread.safe|thread.affinity|single.thread|producer' tx_service/include/cc/cc_shard.h | head -15
echo
echo "== Check which threads can call EnqueueLazyFree by examining call flow =="
rg -n -B 5 'EnqueueLazyFree' tx_service/include/cc/object_cc_map.h | head -40Repository: eloqdata/tx_service
Length of output: 4132
🏁 Script executed:
#!/bin/bash
echo "== Verify counter increment/decrement paths are balanced =="
echo "Enqueue path:"
sed -n '777,787p' tx_service/src/cc/cc_shard.cpp | grep -E 'fetch_add|fetch_sub|emplace_back|pop_back'
echo
echo "Dequeue path:"
sed -n '789,810p' tx_service/src/cc/cc_shard.cpp | grep -E 'fetch_add|fetch_sub|emplace_back|pop_back'
echo
echo "== Check destructor path (cleanup) =="
sed -n '243,248p' tx_service/src/cc/cc_shard.cpp
echo
echo "== Verify all queue modification sites =="
rg -n 'lazy_free_queue_\.(emplace|push|pop|clear)' tx_service/src/cc/cc_shard.cppRepository: eloqdata/tx_service
Length of output: 787
Add explicit synchronization for lazy-free queue or document strict single-thread affinity.
The lazy_free_queue_ std::vector has concurrent access from multiple producer threads (EnqueueLazyFree called during command processing) and a single consumer (ProcessLazyFreeQueue in processor loop), but no synchronization guards. The atomic counter alone does not protect vector operations—emplace_back and pop_back are data races. While counter increment/decrement is balanced (fetch_add(1) on enqueue, fetch_sub(1) on dequeue), correctness depends on an undocumented implicit thread-affinity assumption that is not enforced at the API level. Either add mutex protection around vector accesses or explicitly document that EnqueueLazyFree must only be called from a single designated thread per shard.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@tx_service/include/cc/cc_shard.h` around lines 455 - 457, lazy_free_queue_ is
a std::vector accessed concurrently by EnqueueLazyFree (multiple producers) and
ProcessLazyFreeQueue (single consumer) without synchronization, causing data
races; fix by adding explicit synchronization: protect all accesses and
mutations of lazy_free_queue_ (e.g., push_back, pop_back, clear) with a mutex
(e.g., lazy_free_mutex_) used by EnqueueLazyFree and ProcessLazyFreeQueue, or
alternatively change the API and document/ enforce strict single-thread affinity
so EnqueueLazyFree may only be called from the shard's designated thread (update
comments and any assertions in EnqueueLazyFree/ProcessLazyFreeQueue); ensure the
existing atomic counter remains consistent with the guarded operations.
Here are some reminders before you submit the pull request
fixes eloqdb/tx_service#issue_id./mtr --suite=mono_main,mono_multi,mono_basicSummary by CodeRabbit
New Features
Performance Improvements