Skip to content

feat: add lazy delete scheduling of txobject#480

Merged
thweetkomputer merged 2 commits into
mainfrom
feat-lazy-delete-zc
May 8, 2026
Merged

feat: add lazy delete scheduling of txobject#480
thweetkomputer merged 2 commits into
mainfrom
feat-lazy-delete-zc

Conversation

@thweetkomputer

@thweetkomputer thweetkomputer commented May 8, 2026

Copy link
Copy Markdown
Collaborator

Here are some reminders before you submit the pull request

  • Add tests for the change
  • Document changes
  • Reference the link of issue using fixes eloqdb/tx_service#issue_id
  • Reference the link of RFC if exists
  • Pass ./mtr --suite=mono_main,mono_multi,mono_basic

Summary by CodeRabbit

  • New Features

    • Introduced lazy deletion capability that allows object memory release to be deferred to dedicated processing phases rather than immediate deallocation
  • Performance Improvements

    • Deleted objects are now queued and processed in time-budgeted batches, reducing immediate processing overhead and distributing cleanup work more efficiently across processing cycles

@coderabbitai

coderabbitai Bot commented May 8, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Rate limit exceeded

@thweetkomputer has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 39 minutes and 11 seconds before requesting another review.

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 @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

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 configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 5aa2a84c-b22c-448b-9880-234d50b0b8ff

📥 Commits

Reviewing files that changed from the base of the PR and between aec8d06 and 04e41e1.

📒 Files selected for processing (1)
  • tx_service/src/cc/cc_shard.cpp

Walkthrough

This 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.

Changes

Lazy-Free Object Deallocation Infrastructure

Layer / File(s) Summary
Command Interface Contract
tx_service/include/tx_command.h
Adds virtual IsLazyDelete() method to TxCommand with default false return value, allowing subclasses to opt into lazy deletion.
CcShard Queue API & Storage
tx_service/include/cc/cc_shard.h
Forward-declares struct TxObject; adds public EnqueueLazyFree(std::unique_ptr<TxObject>) and ProcessLazyFreeQueue() methods; adds private lazy_free_queue_ vector and lazy_free_queue_size_ atomic counter; updates IsIdle() to check queue emptiness.
CcShard Implementation
tx_service/src/cc/cc_shard.cpp
Implements EnqueueLazyFree() to push objects, increment size counter, and notify processor; implements ProcessLazyFreeQueue() to drain queue within 50-microsecond time budget; destructor clears queue and resets size counter.
ObjectCcMap Commit Routing
tx_service/include/cc/object_cc_map.h
Modifies CommitCommandOnPayload() and CommitCommandOnDirtyPayload() to branch on cmd.IsLazyDelete(): lazy deletes enqueue via shard_->EnqueueLazyFree(); non-lazy deletes set payload to nullptr.
Processor Wiring & Loop Integration
tx_service/include/cc/local_cc_shards.h, tx_service/include/tx_service.h
LocalCcShards::ProcessLazyFreeQueue(thd_id) delegates to per-shard processing; TxProcessor::RunOneRound() calls lazy-free processing during low-priority phase and accumulates result into req_cnt.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • eloqdata/tx_service#256: Modifies delete-handling semantics in ObjectCcMap's commit paths and TxCommand interface.
  • eloqdata/tx_service#311: Adds a secondary queue to CcShard with enqueue/process APIs and processor loop integration.

Suggested reviewers

  • liunyl
  • MrGuin
  • githubzilla

Poem

A queue of objects waits its time,
Deferred deletion, so sublime,
Lazy frees in budgeted grace,
Keeping memory's frantic pace ⏰🐰

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning The PR description contains only the template checklist without any actual content describing the changes, objectives, or context of the lazy delete feature implementation. Add a detailed description explaining the lazy delete feature, why it's needed, how it works, and include references to related issues and RFC if available.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main feature being added: lazy delete scheduling of txobject, which aligns with all the changes across the codebase.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat-lazy-delete-zc

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.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
tx_service/include/tx_service.h (1)

411-411: 🏗️ Heavy lift

Please 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

📥 Commits

Reviewing files that changed from the base of the PR and between f333a22 and aec8d06.

📒 Files selected for processing (6)
  • tx_service/include/cc/cc_shard.h
  • tx_service/include/cc/local_cc_shards.h
  • tx_service/include/cc/object_cc_map.h
  • tx_service/include/tx_command.h
  • tx_service/include/tx_service.h
  • tx_service/src/cc/cc_shard.cpp

Comment on lines +455 to +457
void EnqueueLazyFree(std::unique_ptr<TxObject> obj);

size_t ProcessLazyFreeQueue();

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 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=h

Repository: 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 -40

Repository: 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 -20

Repository: 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.cpp

Repository: 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 -40

Repository: 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.cpp

Repository: 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.

@thweetkomputer thweetkomputer merged commit 64554e4 into main May 8, 2026
4 checks passed
@thweetkomputer thweetkomputer deleted the feat-lazy-delete-zc branch May 8, 2026 03:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants