Skip to content

Make heap apply retry loop configurable via spock.read_retry_count#475

Merged
mason-sharp merged 3 commits into
mainfrom
SPOC-553
May 25, 2026
Merged

Make heap apply retry loop configurable via spock.read_retry_count#475
mason-sharp merged 3 commits into
mainfrom
SPOC-553

Conversation

@ibrarahmad

Copy link
Copy Markdown
Contributor

spock_apply_heap_update() and spock_apply_heap_delete() hardcoded the retry count at 5 when the local tuple could not be found. Expose this as a GUC (default 5, range 0..100, PGC_SIGHUP) so deployments hitting out-of-order arrivals can tune the loop without rebuilding.

spock_apply_heap_update() and spock_apply_heap_delete() hardcoded the
retry count at 5 when the local tuple could not be found.  Expose this
as a GUC (default 5, range 0..100, PGC_SIGHUP) so deployments hitting
out-of-order arrivals can tune the loop without rebuilding.
@ibrarahmad ibrarahmad requested a review from mason-sharp May 20, 2026 12:43
@coderabbitai

coderabbitai Bot commented May 20, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds a SIGHUP-scoped GUC spock.read_retry_count (int, 0–100, default 5) exported as spock_read_retry_count; apply-worker retry loops for heap UPDATE/DELETE now use this variable instead of a hardcoded 5. Includes docs and an end-to-end TAP test.

Changes

Configurable Read Retry Count

Layer / File(s) Summary
GUC declaration and registration
include/spock.h, src/spock.c, docs/configuring.md
Exports spock_read_retry_count and registers the spock.read_retry_count GUC (PGC_SIGHUP, 0–100, default 5); documents the setting and reload semantics.
Apply path integration
src/spock_apply_heap.c
Adds #include "spock.h" and replaces the hardcoded retry bound (5) with spock_read_retry_count in spock_apply_heap_update() and spock_apply_heap_delete().
End-to-end TAP test
tests/tap/t/030_read_retry_count_guc.pl
New TAP test verifies default, pg_settings metadata, ALTER SYSTEM SET + pg_reload_conf(), ALTER SYSTEM RESET, and bounds enforcement for the GUC.

Poem

🐰 I nibbled code beneath the moon,
A counter fixed now freed too soon,
Five hops once held the retry gate,
Now zero–hundred choose the fate,
Apply workers pause, then try — hooray!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: exposing a hardcoded retry loop count as a configurable GUC parameter named spock.read_retry_count.
Description check ✅ Passed The description directly explains the change: it documents that the retry count in heap apply functions was hardcoded at 5, and is now exposed as a configurable GUC with specified parameters.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
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 SPOC-553

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.

@codacy-production

codacy-production Bot commented May 20, 2026

Copy link
Copy Markdown

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

🟢 Metrics 0 duplication

Metric Results
Duplication 0

View in Codacy

NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/spock_apply_heap.c (1)

972-989: ⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Initialize lookup state and always perform an initial tuple read before retries.

With spock.read_retry_count = 0, these loops never execute, so found is read uninitialized and the code may take an arbitrary branch. It also skips the initial local tuple lookup entirely.

💡 Proposed fix
@@
-	bool		found;
+	bool		found = false;
@@
-	retry = 0;
-	while (retry < spock_read_retry_count)
-	{
-		found = FindReplTupleInLocalRel(edata, relinfo->ri_RelationDesc,
-										edata->targetRel->idxoid,
-										remoteslot, &localslot,
-										false);
-		if (found)
-			break;
-
-		wait_for_previous_transaction();
-		retry++;
-	}
+	found = FindReplTupleInLocalRel(edata, relinfo->ri_RelationDesc,
+									edata->targetRel->idxoid,
+									remoteslot, &localslot,
+									false);
+	retry = 0;
+	while (!found && retry < spock_read_retry_count)
+	{
+		wait_for_previous_transaction();
+		retry++;
+		found = FindReplTupleInLocalRel(edata, relinfo->ri_RelationDesc,
+										edata->targetRel->idxoid,
+										remoteslot, &localslot,
+										false);
+	}

Apply the same pattern in both spock_apply_heap_update() and spock_apply_heap_delete().

Also applies to: 1089-1106

🤖 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 `@src/spock_apply_heap.c` around lines 972 - 989, Initialize the lookup state
and perform an initial FindReplTupleInLocalRel call before entering the retry
loop to avoid reading the uninitialized variable `found` when
`spock_read_retry_count` is 0; specifically in functions
`spock_apply_heap_update()` and `spock_apply_heap_delete()` set `retry = 0`,
initialize `found = false` (or equivalent), call `FindReplTupleInLocalRel(edata,
relinfo->ri_RelationDesc, edata->targetRel->idxoid, remoteslot, &localslot,
false)` once and handle the result before entering the while (retry <
spock_read_retry_count) loop, then keep the existing
wait_for_previous_transaction() / retry++ logic for subsequent attempts.
🤖 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.

Outside diff comments:
In `@src/spock_apply_heap.c`:
- Around line 972-989: Initialize the lookup state and perform an initial
FindReplTupleInLocalRel call before entering the retry loop to avoid reading the
uninitialized variable `found` when `spock_read_retry_count` is 0; specifically
in functions `spock_apply_heap_update()` and `spock_apply_heap_delete()` set
`retry = 0`, initialize `found = false` (or equivalent), call
`FindReplTupleInLocalRel(edata, relinfo->ri_RelationDesc,
edata->targetRel->idxoid, remoteslot, &localslot, false)` once and handle the
result before entering the while (retry < spock_read_retry_count) loop, then
keep the existing wait_for_previous_transaction() / retry++ logic for subsequent
attempts.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: e3e32207-725a-4461-8734-9ffbaae7466f

📥 Commits

Reviewing files that changed from the base of the PR and between 3886058 and 135a35a.

📒 Files selected for processing (4)
  • include/spock.h
  • src/spock.c
  • src/spock_apply_heap.c
  • tests/tap/t/030_read_retry_count_guc.pl

Comment thread src/spock.c Outdated

@danolivo danolivo left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM

@mason-sharp mason-sharp left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Can you also update the docs for the new GUC?

@danolivo danolivo added the skip-test-nightly Skip this PR in the nightly TAP workflow label May 25, 2026
Add a configuring.md entry describing the retry behavior, the
0-disables-retries semantics, the 0-100 range, the default of 5,
and the SIGHUP reload behavior.

@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

🤖 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 `@docs/configuring.md`:
- Around line 234-236: The fenced code block containing the configuration line
spock.read_retry_count = 5 is missing a language specifier; update that fenced
block to use the ini language identifier (i.e., change the backtick fence to
```ini) so the block is marked as INI for syntax highlighting and to satisfy the
MD040 lint rule, matching other examples like the postgresql.conf snippets.
🪄 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: 21dd50fa-a2b7-4010-8293-bbfcc9a46aad

📥 Commits

Reviewing files that changed from the base of the PR and between e8b3b2e and 7cc757e.

📒 Files selected for processing (1)
  • docs/configuring.md

Comment thread docs/configuring.md
Comment on lines +234 to +236
```
spock.read_retry_count = 5
```

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 | 🟡 Minor | ⚡ Quick win

Add language specifier to the fenced code block.

The fenced code block should specify ini as the language identifier for proper syntax highlighting and to comply with markdown best practices.

📝 Proposed fix
-```
+```ini
 spock.read_retry_count = 5
</details>

Based on learnings: Static analysis flagged this as MD040 (fenced-code-language). Other configuration examples in this file (lines 264-274) use `ini` for postgresql.conf settings.

<details>
<summary>🧰 Tools</summary>

<details>
<summary>🪛 markdownlint-cli2 (0.22.1)</summary>

[warning] 234-234: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

</details>

</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @docs/configuring.md around lines 234 - 236, The fenced code block containing
the configuration line spock.read_retry_count = 5 is missing a language
specifier; update that fenced block to use the ini language identifier (i.e.,
change the backtick fence to ```ini) so the block is marked as INI for syntax
highlighting and to satisfy the MD040 lint rule, matching other examples like
the postgresql.conf snippets.


</details>

<!-- fingerprinting:phantom:triton:puma -->

<!-- This is an auto-generated comment by CodeRabbit -->

@mason-sharp mason-sharp merged commit db7a374 into main May 25, 2026
17 of 18 checks passed
@mason-sharp mason-sharp deleted the SPOC-553 branch May 25, 2026 19:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

6.0 skip-test-nightly Skip this PR in the nightly TAP workflow

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants