Skip to content

Conversation

@thebrianchen
Copy link

Recreating #1222 to merge against PR without deleting comment history.

@thebrianchen thebrianchen self-assigned this Jun 25, 2020
@googlebot googlebot added the cla: yes This human has signed the Contributor License Agreement. label Jun 25, 2020
@codecov
Copy link

codecov bot commented Jun 25, 2020

Codecov Report

Merging #1243 into master will decrease coverage by 0.00%.
The diff coverage is 100.00%.

Impacted file tree graph

@@            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              
Impacted Files Coverage Δ
dev/src/bulk-writer.ts 98.68% <100.00%> (-0.19%) ⬇️
dev/src/write-batch.ts 100.00% <100.00%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update b83874c...aaa5fed. Read the comment docs.

import {Deferred, wrapError} from './util';
import {Deferred, getRetryCodes, wrapError} from './util';
import {BatchWriteResult, WriteBatch, WriteResult} from './write-batch';
import {Status} from 'google-gax';
Copy link
Contributor

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.

Copy link
Author

Choose a reason for hiding this comment

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

done.

error?: Error
): number[] {
const indexesToRetry: number[] = [];
if (error) {
Copy link
Contributor

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?

Copy link
Author

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) {
Copy link
Contributor

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 :)

Copy link
Author

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.

this.completedDeferred.resolve();

if (indexesToRetry.length === 0) {
this.completedDeferred.resolve();
Copy link
Contributor

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.

Copy link
Contributor

@schmidt-sebastian schmidt-sebastian left a 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.

results = await this.writeBatch.bulkCommit();
} catch (err) {
// Map the failure to each individual write's result.
results = [...this.pendingOps.keys()].map(key => {
Copy link
Contributor

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?

Copy link
Author

Choose a reason for hiding this comment

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

done.

} else {
for (let i = 0; i < this.opCount; i++) {
this.resultsMap.get(i)!.reject(error);
processResults(results: BatchWriteResult[], shouldRetry: boolean): void {
Copy link
Contributor

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.

Copy link
Author

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.

}
}

this.processResults(results, /* shouldRetry= */ false);
Copy link
Contributor

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.

Copy link
Author

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.

Comment on lines +250 to +251
this.completedDeferred.resolve();
return;
Copy link
Contributor

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.

Copy link
Author

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.

return code !== undefined && retryCodes.includes(code);
}

has(path: string): boolean {
Copy link
Contributor

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(), ...).

Copy link
Author

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,
Copy link
Contributor

Choose a reason for hiding this comment

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

Please document.

Copy link
Author

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[]
Copy link
Contributor

Choose a reason for hiding this comment

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

Please document.

Copy link
Author

Choose a reason for hiding this comment

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

done.

@thebrianchen thebrianchen merged commit 6007e43 into master Jun 29, 2020
@thebrianchen thebrianchen deleted the bc/retry-failed-writes-2 branch June 29, 2020 18:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cla: yes This human has signed the Contributor License Agreement.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants