-
Notifications
You must be signed in to change notification settings - Fork 149
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
fix: Optimize Transaction PITR #2002
fix: Optimize Transaction PITR #2002
Conversation
🤖 I detect that the PR title and the commit message differ and there's only one commit. To use the PR title for the commit history, you can use Github's automerge feature with squashing, or use -- conventional-commit-lint bot |
requestTag: this._requestTag, | ||
}) | ||
.then(() => {}); | ||
async commit(): Promise<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.
This is purely a refactor to use async
syntax.
.then(resp => { | ||
this._transactionId = resp.transaction!; | ||
}); | ||
const resp = await this._firestore.request< |
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 is purely a refactor to use async
syntax.
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. Nice improvement.
@@ -5319,30 +5319,6 @@ describe('Transaction class', () => { | |||
expect(snapshot.exists).to.be.true; | |||
expect(snapshot.get('foo')).to.equal(1); | |||
}); | |||
|
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 added client side exceptions to attempting write on readonly transaction, so this integration test is no longer valid.
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.
Direction looks good. There are a few comments for your consideration.
@@ -265,6 +290,9 @@ export class Transaction implements firestore.Transaction { | |||
documentRef: firestore.DocumentReference<AppModelType, DbModelType>, | |||
data: firestore.WithFieldValue<AppModelType> | |||
): Transaction { | |||
if (this._readOnly) { | |||
throw new Error(READ_ONLY_WRITE_ERROR_MSG); | |||
} |
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.
There has been a recent movement in the SDKs to leave runtime validation up to the server. In this case, I think performing the validation in the client is acceptable because a read-only transaction should never be writable, that will not change. Calling this out for your 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.
For ReadTime transactions, we don't call commit which would normally be when backend could respond. So this is less preference, and more technical requirement.
.then(resp => { | ||
this._transactionId = resp.transaction!; | ||
}); | ||
const resp = await this._firestore.request< |
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. Nice improvement.
}) | ||
.then(() => {}); | ||
async commit(): Promise<void> { | ||
if (this._readTime) { |
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.
Is it possible to check if the _readOnly
flag is set instead of _readTime
. The type safety will not guarantee runTransaction will be called for a readOnly transaction without readTime being set.
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.
ReadOnly but without ReadTime are still transactions that have BeginTransaction
and Commit
request. That is why I have to use _readTime
, since only in the subset of cases where the transaction if ReadOnly AND with ReadTime can we do the optimization.
However, this is also a little weird of a check that I added, since this will only occur if there is a bug in SDK. The customer never has an opportunity to call commit()
on transactions. Calling commit()
is done implicitly when update lambda completes. So this should never happen so long as our SDK logic is correct.
async runTransactionOnce<T>( | ||
updateFunction: (transaction: Transaction) => Promise<T> | ||
): Promise<T> { | ||
if (!this._readTime) { |
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.
Same comment with respect to using _readOnly
vs _readTime
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.
Again this optimization only works for the subset of ReadOnly transaction that have ReadTime.
); | ||
} | ||
const result = await promise; | ||
if (!this._readTime) { |
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.
same
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.
dido
For transactions with read time, the begin transaction and commit can be omitted, thereby decreasing latency.
b/324245706