-
Notifications
You must be signed in to change notification settings - Fork 103
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: support RPC priority #1282
Conversation
Also adding @AVaksman who is working on tagging which may touch similar code paths. |
samples/rpc-priority.js
Outdated
ORDER BY AlbumTitle`; | ||
|
||
try { | ||
const [rows] = await database.run({ |
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.
It would be great to add a comment to say that we're explicitly lowering the priority of this query by setting this option.
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/transaction.ts
Outdated
@@ -1253,15 +1261,15 @@ export class Transaction extends Dml { | |||
|
|||
batchUpdate( | |||
queries: Array<string | Statement>, | |||
gaxOptions?: CallOptions | |||
options?: BatchUpdateOptions |
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.
Because of changes like this, we may actually have to make the type changes separately in time for the breaking change release we'll do in early January. Do you think that would be ok?
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.
Yeah, I'll extract this change to a separate PR.
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.
Following @JustinBeckwith's suggestion in #1278 (comment), we could also change this parameter (and others) to BatchUpdateOptions | CallOptions
. The definition of this and the other methods would then look something like this:
batchUpdate(
queries: Array<string | Statement>,
optionsOrCallback?: BatchUpdateOptions | CallOptions | BatchUpdateCallback,
cb?: BatchUpdateCallback
): Promise<BatchUpdateResponse> | void {
const options =
typeof optionsOrCallback === 'object' ? optionsOrCallback : {};
const callback =
typeof optionsOrCallback === 'function' ? optionsOrCallback : cb!;
const gaxOpts =
'gaxOptions' in options
? (options as BatchUpdateOptions).gaxOptions
: options;
...
}
(@JustinBeckwith Please feel free to correct me if I misunderstood your 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.
@JustinBeckwith Friendly ping on this. Would you mind giving us your input/opinion on the above?
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 this out for CommitStats. It works to avoid the breaking change. But there is a caveat that @AVaksman pointed at which is that if options doesn't have gaxOptions
then we pass the options
as a whole even if it is not a CallOptions
.
Is this ok?
I tried to use a Discriminating Union but then we need the user to specify the descriminator field, which would end up being a breaking change anyway.
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 assume there is no other way to do this than the idea you suggested @olavloite . I'll be going ahead with this implementation for CommitStats. So if you could do the same in this PR, then that works.
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.
Yeah - we really want to avoid breaking changes in these library unless it's unreasonable to avoid. We're starting to evaluate the possibility of backporting fixes to prior major releases, so the cost of these is going to go waaaaay up. I would recommend avoiding the break if you can.
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've changed the different options arguments to BatchUpdateOptions | CallOptions
(and similar) and added type checking where necessary. That should make this a non-breaking change.
samples/rpc-priority.js
Outdated
|
||
'use strict'; | ||
|
||
async function queryWithRpcPriority(instanceId, databaseId, projectId) { |
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 are no region tags here, so these samples won't be usable within cloud.google.com. Should we add them?
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.
Yes, eventually, but they are not known yet.
samples/rpc-priority.js
Outdated
ORDER BY AlbumTitle`; | ||
|
||
try { | ||
const [rows] = await database.run({ |
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.
When using an async function like this, we expect a wrapping main
function, and an inner async function that's inside the region tag. Here is a good example:
https://github.com/googleapis/nodejs-bigquery/blob/master/samples/createJob.js
For the full description of how these work and why, check out:
https://g3doc.corp.google.com/company/teams/cloud-devrel/dpe/samples/nodejs.md?cl=head
@skuruppu it looks like every sample in this repo needs to be checked for conformance against that rubric :/
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.
Ack @JustinBeckwith, I didn't realize. We'll do this as a separate cleanup effort. Tracked in #1295.
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 information. I've updated this specific sample based on the example you provided. I unfortunately am not allowed to access the documentation that you linked.
samples/rpc-priority.js
Outdated
|
||
rows.forEach(row => { | ||
const json = row.toJSON(); | ||
const marketingBudget = json.MarketingBudget |
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'm curious - why is it important this value is null
vs undefined
or ''
?
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.
Good point, it's not (lazy copy-paste from a different sample). I removed that specific part.
samples/rpc-priority.js
Outdated
} | ||
} | ||
|
||
require('yargs') |
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.
With all of our new samples, we no longer use yargs
and instead rely on positional parameters. See the rubric.
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.
Changed to positional parameters.
src/transaction.ts
Outdated
@@ -1253,15 +1261,15 @@ export class Transaction extends Dml { | |||
|
|||
batchUpdate( | |||
queries: Array<string | Statement>, | |||
gaxOptions?: CallOptions | |||
options?: BatchUpdateOptions |
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.
Yeah - we really want to avoid breaking changes in these library unless it's unreasonable to avoid. We're starting to evaluate the possibility of backporting fixes to prior major releases, so the cost of these is going to go waaaaay up. I would recommend avoiding the break if you can.
Codecov Report
@@ Coverage Diff @@
## master #1282 +/- ##
=======================================
Coverage 98.60% 98.60%
=======================================
Files 23 23
Lines 21942 21960 +18
Branches 1229 1235 +6
=======================================
+ Hits 21636 21654 +18
Misses 297 297
Partials 9 9
Continue to review full report at Codecov.
|
src/transaction.ts
Outdated
@@ -60,6 +61,7 @@ export interface RequestOptions { | |||
} | |||
|
|||
export interface CommitOptions { | |||
requestOptions?: IRequestOptions; |
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 IRequestOptions
interface will contain RPC priority options and the tagging options. However CommitOptions
should not support tagging options as a parameter.
I am suggesting either to define a separate interface with just a priority
option or another way would be to use some ts magic
requestOptions?: Pick<IRequestOptions, 'priority'>;
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 think we also need to think of a different name, since we have a same name parameter in ExecuteSqlRequest
and BatchUpdateOptions
interfaces, in which "requestOptions" will support priority
and a requestTag
.
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.
perhaps "commitRequestOptions" and "transactionRequetOptions", any suggestions are most welcome.
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 think doing something like:
requestOptions?: Omit<IRequestOptions, 'request_tag'>;
would be my preference.
I'm not sure about having to name the request options differently in each interface though. We want to keep our interfaces mirroring the protos as much possible. I think it's sufficient to use Pick/Omit to make it clear which of the IRequestOptions fields are available for use or not. In the worst case, we can just add documentation to make it clear which fields are supported.
src/transaction.ts
Outdated
@@ -123,6 +126,7 @@ export interface BatchUpdateCallback { | |||
response?: spannerClient.spanner.v1.ExecuteBatchDmlResponse | |||
): void; | |||
} | |||
export type BatchUpdateOptions = CommitOptions; |
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.
Also to have in mind that "requestOptions" (or "transactionRequetOptions" or better name) of BatchUpdateOptions
will support requestTag
in the future.
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.
Once proto changes for tagging is merged something like this could be used
requestOptions?: Omit<IRequestOptions, 'transactionTag'>
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 guess that means we have to explicitly create a BatchUpdateOptions
interface as it's not the same as CommitOptions
.
src/transaction.ts
Outdated
@@ -76,6 +78,7 @@ export interface ExecuteSqlRequest extends Statement, RequestOptions { | |||
partitionToken?: Uint8Array | string; | |||
seqno?: number; | |||
queryOptions?: IQueryOptions; | |||
requestOptions?: IRequestOptions; |
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.
Probably should not use the same property name as in CommitOptions
interface since CommitOptions.requestOptions
will only support priority
parameter and in both ExecuteSqlRequest
and BatchUpdateOptions
same property name will support requestTag
parameter
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 think it's fine as long as we use Pick/Omit to make it clear which fields are supported/not supported.
I merged the codegen PR so once we rebase, we can continue the discussion. |
@olavloite if you could make the changes such that this PR can be merged before #1286, that would be great. |
I think that there's something strange going on with that codegen. The It seems that the regenerate step is missing the actual |
I've tried to regenerate locally and this is what I get
|
Hmmmm I'm not sure what's going on. I asked the Node folks for help. |
The issue should be fixed now, please rebase again. |
src/transaction.ts
Outdated
@@ -61,7 +61,7 @@ export interface RequestOptions { | |||
} | |||
|
|||
export interface CommitOptions { | |||
requestOptions?: IRequestOptions; | |||
requestOptions?: Omit<IRequestOptions, 'requestTag'>; |
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 believe it should be
requestOptions?: Pick<IRequestOptions, 'priority'>;
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, I don't think that's correct. CommitOptions
are used for blind writes such as database.table('some-table').insert(..)
, and those should support setting a transaction tag.
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.
(After our conversation earlier today): I've removed transaction-tag
from CommitOptions
.
projectId: projectId, | ||
}); | ||
|
||
async function queryWithRpcPriority(instanceId, databaseId) { |
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 forgot to mention this earlier. There are no code samples for this feature that will get pulled in from docs. So there's a question of whether we should remove the sample and just add an integration test. There's no way to test if the priority is being accepted by the backend but at least you're able to set it.
What do you think?
// TODO: Enable when RPC Priority has been released. | ||
it.skip('should use request options', 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.
If we choose to keep the sample then you can unskip this now.
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.
Argh. I missed this one and went ahead and merged without it. I've opened a new PR for enabling it here: #1338
Adds support for setting RPC priority.
This PR also uses some of the changes that are introduced in #1254.