Skip to content

feat: Add configurable retry timing for RunTransactionAsync#11564

Merged
jskeet merged 1 commit intogoogleapis:mainfrom
jskeet:issue-10513
Jan 29, 2024
Merged

feat: Add configurable retry timing for RunTransactionAsync#11564
jskeet merged 1 commit intogoogleapis:mainfrom
jskeet:issue-10513

Conversation

@jskeet
Copy link
Copy Markdown
Collaborator

@jskeet jskeet commented Jan 19, 2024

There are further changes to come in terms of transaction retry, but this is at least a start. Note that this changes the default backoff from "none at all" to "100ms initial, with a multiplier of 1.3". That's a more reasonable default, and it seems unlikely that customers would actually depend on there being no backoff.

Fixes #10513

@jskeet jskeet added the do not merge Indicates a pull request not ready for merge, due to either quality or timing. label Jan 19, 2024
@jskeet jskeet requested a review from a team January 19, 2024 16:55
@jskeet
Copy link
Copy Markdown
Collaborator Author

jskeet commented Jan 19, 2024

Marked as "do not merge" as while this is the complete production code as far as I'm aware, there are no tests yet - I wanted to get feedback on the API and overall plan first.

@@ -410,8 +420,12 @@ public async Task<T> RunTransactionAsync<T>(Func<Transaction, Task<T>> callback,
}
catch (RpcException e) when (CheckRetry(e, ref rollback))
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.

I think there's a bug here that was there before.

If commit fails with aborted and there are attempts left, we never rollback that failed transaction right? Or is it OK not to rollback it because it already failed?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I think it's okay, but we'll need to check. We definitely need to make changes here in general though - this PR is only attempting to affect the timing.

Comment on lines +426 to +428
// This is essentially the inner loop of RetryAttempt.CreateRetrySequence.
await scheduler.Delay(timing.BackoffJitter.GetDelay(backoff), cancellationToken).ConfigureAwait(false);
backoff = timing.NextBackoff(backoff);
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.

I think this is clearer inside the catch.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I'm generally nervous of doing stuff in catch blocks. There are some oddities about how code executes there - not that I can remember details. Let's chat next week.

/// <summary>
/// The number of times the transaction will be attempted before failing.
/// </summary>
public int MaxAttempts { get; }
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.

Could we deprecate this one instead of ignoring the one in RetrySettings?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Feels a bit like overkill if most people won't need to touch the timing - creating a retry setting is relatively complex. Happy to chat about it though.

@jskeet
Copy link
Copy Markdown
Collaborator Author

jskeet commented Jan 23, 2024

Revamped to just use an underlying RetrySettings - PTAL.

Copy link
Copy Markdown
Contributor

@amanda-tarafa amanda-tarafa left a comment

Choose a reason for hiding this comment

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

LGTM, thanks!

There are further changes to come in terms of transaction retry, but
this is at least a start. Note that this changes the default backoff
from "none at all" to "100ms initial, with a multiplier of 1.3".
That's a more reasonable default, and it seems unlikely that
customers would actually *depend* on there being no backoff.

Fixes googleapis#10513
@jskeet jskeet removed the do not merge Indicates a pull request not ready for merge, due to either quality or timing. label Jan 29, 2024
@jskeet
Copy link
Copy Markdown
Collaborator Author

jskeet commented Jan 29, 2024

I've added tests, and this is now ready to merge if you're happy with it. (Again, it's not the final word on transaction retries - but it's at least an improvement in terms of timing.)

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.

Google.Cloud.Firestore: Backoff on FirestoreDb.RunTransactionAsync retry

2 participants