Skip to content

feat: aborted-transaction retry policy and client integration#18

Open
mlwelles wants to merge 1 commit into
matthewmcneely:mainfrom
mlwelles:feature/retry-record
Open

feat: aborted-transaction retry policy and client integration#18
mlwelles wants to merge 1 commit into
matthewmcneely:mainfrom
mlwelles:feature/retry-record

Conversation

@mlwelles

@mlwelles mlwelles commented Jun 4, 2026

Copy link
Copy Markdown

Adds a retry layer for aborted Dgraph transactions:

  • RetryPolicy / DefaultRetryPolicy and a runner with exponential backoff (retry.go).
  • Exposed on the client via a new Client.WithRetry(ctx, policy, fn) method.

Self-contained: retry.go + the WithRetry interface method on Client; builds and tests green. The bulk-loader PR (#19) stacks on this.

Part of a series upstreaming work from a downstream fork; opened for review/discussion.

@mlwelles mlwelles requested a review from matthewmcneely as a code owner June 4, 2026 17:11
@mlwelles mlwelles force-pushed the feature/retry-record branch from 21760f3 to 67c0b31 Compare June 4, 2026 17:12

@cubic-dev-ai cubic-dev-ai 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.

2 issues found across 2 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="retry.go">

<violation number="1" location="retry.go:46">
P2: MaxDelay cap is applied before jitter, so actual backoff can exceed the configured maximum. The `MaxDelay` field is documented as capping the backoff so "No single delay exceeds this," but the `delay()` method applies the cap before adding positive jitter, allowing the final delay to exceed `MaxDelay`.</violation>

<violation number="2" location="retry.go:77">
P2: Negative `MaxRetries` can skip the loop entirely and trigger the panic path.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread retry.go

// delay computes the backoff duration for a given attempt (0-indexed).
// Formula: min(BaseDelay * 2^attempt, MaxDelay) + random(0, delay * Jitter)
func (p RetryPolicy) delay(attempt int) time.Duration {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2: MaxDelay cap is applied before jitter, so actual backoff can exceed the configured maximum. The MaxDelay field is documented as capping the backoff so "No single delay exceeds this," but the delay() method applies the cap before adding positive jitter, allowing the final delay to exceed MaxDelay.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At retry.go, line 46:

<comment>MaxDelay cap is applied before jitter, so actual backoff can exceed the configured maximum. The `MaxDelay` field is documented as capping the backoff so "No single delay exceeds this," but the `delay()` method applies the cap before adding positive jitter, allowing the final delay to exceed `MaxDelay`.</comment>

<file context>
@@ -0,0 +1,96 @@
+
+// delay computes the backoff duration for a given attempt (0-indexed).
+// Formula: min(BaseDelay * 2^attempt, MaxDelay) + random(0, delay * Jitter)
+func (p RetryPolicy) delay(attempt int) time.Duration {
+	d := p.BaseDelay * time.Duration(1<<uint(attempt))
+	if d > p.MaxDelay {
</file context>

Comment thread retry.go
// return client.Insert(ctx, &entity)
// })
func (c client) WithRetry(ctx context.Context, policy RetryPolicy, fn func() error) error {
for attempt := range policy.MaxRetries + 1 {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2: Negative MaxRetries can skip the loop entirely and trigger the panic path.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At retry.go, line 77:

<comment>Negative `MaxRetries` can skip the loop entirely and trigger the panic path.</comment>

<file context>
@@ -0,0 +1,96 @@
+//	    return client.Insert(ctx, &entity)
+//	})
+func (c client) WithRetry(ctx context.Context, policy RetryPolicy, fn func() error) error {
+	for attempt := range policy.MaxRetries + 1 {
+		err := fn()
+		if err == nil {
</file context>

Add RetryPolicy / DefaultRetryPolicy and a runner that re-executes a
function on aborted Dgraph transactions with exponential backoff
(retry.go), exposed on the client via a WithRetry method.
@mlwelles mlwelles force-pushed the feature/retry-record branch from 67c0b31 to b477c28 Compare June 4, 2026 17:24
@mlwelles mlwelles changed the title feat: aborted-transaction retry policy and runner feat: aborted-transaction retry policy and client integration Jun 4, 2026
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.

1 participant