-
Notifications
You must be signed in to change notification settings - Fork 161
fix: retry ABORTED writes in bulkCommit #1243
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Codecov Report
@@ Coverage Diff @@
## master #1243 +/- ##
==========================================
- Coverage 98.50% 98.50% -0.01%
==========================================
Files 30 30
Lines 18545 18624 +79
Branches 1422 1431 +9
==========================================
+ Hits 18268 18345 +77
- Misses 274 276 +2
Partials 3 3
Continue to review full report at Codecov.
|
dev/src/bulk-writer.ts
Outdated
| import {Deferred, wrapError} from './util'; | ||
| import {Deferred, getRetryCodes, wrapError} from './util'; | ||
| import {BatchWriteResult, WriteBatch, WriteResult} from './write-batch'; | ||
| import {Status} from 'google-gax'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: External imports should go in the first block.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done.
dev/src/bulk-writer.ts
Outdated
| error?: Error | ||
| ): number[] { | ||
| const indexesToRetry: number[] = []; | ||
| if (error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add a small comment here to explain what this is doing?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done.
| try { | ||
| const results = await this.writeBatch.bulkCommit(); | ||
| retryIndexes = this.processResults(originalIndexMap, results); | ||
| } catch (err) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried to see if I could get rid of this re-assignment and got completely carried away. Here is a cleanup:
https://gist.github.com/schmidt-sebastian/702ba33ce0c3515d096089226a762934
Use at your own risk and take at your own consideration :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Huge fan of this organization. I implemented what you did, but changed keys to docPaths since I was a bit confused about what the keys were at first. I think this approach will work with the UpdateBuilder pattern on java as well.
dev/src/bulk-writer.ts
Outdated
| this.completedDeferred.resolve(); | ||
|
|
||
| if (indexesToRetry.length === 0) { | ||
| this.completedDeferred.resolve(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We also need to resolve this when all retry attempts failed. Please also add a test for this.
schmidt-sebastian
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the update. Some naming/comment nits to ruin your weekend.
dev/src/bulk-writer.ts
Outdated
| results = await this.writeBatch.bulkCommit(); | ||
| } catch (err) { | ||
| // Map the failure to each individual write's result. | ||
| results = [...this.pendingOps.keys()].map(key => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should "key" be "path" then?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done.
dev/src/bulk-writer.ts
Outdated
| } else { | ||
| for (let i = 0; i < this.opCount; i++) { | ||
| this.resultsMap.get(i)!.reject(error); | ||
| processResults(results: BatchWriteResult[], shouldRetry: boolean): void { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/shouldRetry/mayRetry (or allowRetry)?
Also might be worth adding @param comments.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
N/A since we're using failRemainingOperations.
dev/src/bulk-writer.ts
Outdated
| } | ||
| } | ||
|
|
||
| this.processResults(results, /* shouldRetry= */ false); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This might be cleaner if this was this.failRemainingOperations(results) and a separate call.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I originally didn't want to copy/paste code, but in this case, it clarifies the behavior much better.
| this.completedDeferred.resolve(); | ||
| return; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could just be a break, this.processResult() would be a no-op.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The map entry is deleted from pendingOps after the promise is resolved in processResults, so an error would be thrown if processResults is called again.
dev/src/bulk-writer.ts
Outdated
| return code !== undefined && retryCodes.includes(code); | ||
| } | ||
|
|
||
| has(path: string): boolean { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's use a more descriptive name here (hasDoc(), hasWrite(), ...).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done.
| constructor(firestore: Firestore); | ||
| constructor( | ||
| firestore: Firestore, | ||
| retryBatch?: WriteBatch, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please document.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done.
| constructor( | ||
| firestore: Firestore, | ||
| retryBatch?: WriteBatch, | ||
| docsToRetry?: string[] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please document.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done.
Recreating #1222 to merge against PR without deleting comment history.