-
Notifications
You must be signed in to change notification settings - Fork 106
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
feat: new transaction feature #1239
feat: new transaction feature #1239
Conversation
Transaction state should move up to the super class
Add a method for building transaction options. Also add a method for detecting if a request is a transaction. Build new transaction options
Corrected getTransactionRequest. Build the request options properly.
When this system test isn’t set to be a readOnly transaction then the error occurs which says too much contention.
Change parseRunSuccess so that it can be used more universally.
parseRunSuccess should move up to the super class because it now needs to be used there.
This change saves the transaction id returned from the server for read calls
Read only tests are needed
Make sure that code using the new transaction option has better performance than code that doesn’t have it.
Use the MockedTransactionWrapper to test requests being passed into the Gapic layer.
Mock out begin transaction. Test for newTransaction consistency type. Mock out commit.
A transaction.run test is needed for lookup, lookup, put, commit.
Add a test for this sequence of operations and ensure it works properly.
Four operations that get all the results for running an aggregation query. Adding another test for these four operations.
Last test suite regarding new transaction unit tests.
Add a bunch of tests for the commit case. Check the commit gapic input.
Begin transaction should be called at least once. Add code here to increment the counter.
Remove commented code too.
Check for expired on most functions and write tests for the expired check.
…anieljbruce/nodejs-datastore into new-transaction-feature-branch
@@ -68,35 +53,13 @@ describe('Run Query', () => { | |||
} | |||
} | |||
|
|||
it('should pass read time into runQuery for transactions', async () => { |
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.
Note that this test is no longer valid because transaction and read time are no longer compatible together as is the case in Python.
throw Error(transactionExpiredError); | ||
} | ||
} | ||
|
||
/** | ||
* Retrieve the entities as a readable object stream. | ||
* |
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: update L381 with new added errors?
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.
Sure. Done.
callback(new Error(transactionExpiredError)); | ||
return; | ||
} | ||
if (this.state === TransactionState.NOT_STARTED) { |
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.
Just wondering what are the allowed states here? NOT_TRANSACTION and IN_PROGRESS?
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.
NOT_TRANSACTION, NOT_STARTED, IN_PROGRESS, EXPIRED.
src/request.ts
Outdated
if (this.state === TransactionState.EXPIRED) { | ||
callback(new Error(transactionExpiredError)); | ||
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.
Do we need to check readTimeAndConsistencyError
here?
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.
No. That check is done further downstream in the call to runQueryStream
. But I did spot some other cases where errors weren't bubbling up and fixed those bugs.
Fix the concurrency tests and move the error reporting outside of the stream, add two tests for the streams to make sure errors get reported.
This makes it so that it is reported in the streams.
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.
LGTM
export function getTransactionRequest( | ||
transaction: Transaction, | ||
options: RunOptions | ||
): TransactionRequestOptions { |
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 add some 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.
Done
src/request.ts
Outdated
if (id) { | ||
reqOpts.readWrite = {previousTransaction: id}; | ||
} | ||
} |
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 there a way to trim down this logic a bit? Seems a bit redundant
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 generated unit tests, corrected them and then reduced this function down to one ternary operation. Previously this was just copy pasted code from before. Search describe('getTransactionRequest', () => {
to see how this function should behave.
I am going to rewrite the getTransactionRequest function so it is a good idea not to change how it works.
Fix the compiler error Change code so that when readOnly is specified then readwrite options are ignored. Fix the unit test to adopt this change.
Add comments, simplify logic in the function.
…anieljbruce/nodejs-datastore into new-transaction-feature-branch
Summary
This PR ensures that transaction read calls will use newTransaction options to begin transactions instead of making a separate
beginTransaction
grpc call.Source code changes
A
#blockWithMutex
function is added and it is used for read calls instead of a#withBeginTransaction
function. This makes it so that all read calls on Transaction will block on the mutex and then call the same method in their super class. Before this change, the read calls on Transaction would block on the mutex, make abeginTransaction
grpc call and then call the same method in their super class. So this change to using#blockWithMutex
omits the extrabeginTransaction
call and instead expects the function it is calling to supply new transaction options.A function
getTransactionRequest
is added which pulls out the code used for building transaction options for abeginTransaction
request. That is because this code is also used to build the new transaction options.TransactionState is moved up to the super class
DatastoreRequest
and a new state is added calledNOT_TRANSACTION
forDataRequests
that are not transactions.parseTransactionResponse
is moved up to the super classDatastoreRequest
and is now used byrunQuery
,runAggregationQuery
andget
to save the transaction id.newTransaction
options are now built ingetRequestOptions
which is used byrunQuery
,runAggregationQuery
andget
to save the transaction id.state
is moved up to theDatastoreRequest
super class because it now has to be used to decide whether or not to build newTransaction options.If a transaction is expired then an error will be thrown when the transaction is used.
ReadOptions are the options shared by Datastore read requests.
new_transaction is a consistency type in ReadOptions. When new_transaction is used in a read request, a new transaction is begun for the request.
System tests added
A system test is added to ensure using new transaction has better latency. System tests are added for runQuery, runAggregationQuery and get for readOnly transactions to ensure readOnly transactions work correctly whether
transaction.run
is called or not.Unit tests added
Unit tests are added for various orders of transaction operations that ensure correct behaviour for when
transaction.run
is used and whentransaction.run
is omitted.lookup, lookup, put, commit
is one order that is tested. The others arerunQuery, lookup, put, commit
,runAggregationQuery, lookup, put, commit
,put, put, lookup, commit
andput, commit
. A unit test is also corrected.Drawbacks
If the user uses
transaction.runQueryStream
or they usetransaction.createReadStream
then the call will not block on a mutex. These methods are not async methods so they cannot wait for a#blockWithMutex
call to complete. If users are currently usingrunQueryStream
orcreateReadStream
concurrently then these multiple read calls may be beginning multiple transactions at the same time using one transaction object which is not ideal.