Skip to content

feat(datastore): add support for request tags#13732

Open
rahulmane-goog wants to merge 4 commits into
googleapis:mainfrom
rahulmane-goog:feat-datastore-request-tags
Open

feat(datastore): add support for request tags#13732
rahulmane-goog wants to merge 4 commits into
googleapis:mainfrom
rahulmane-goog:feat-datastore-request-tags

Conversation

@rahulmane-goog

@rahulmane-goog rahulmane-goog commented Jul 13, 2026

Copy link
Copy Markdown

This PR introduced sending request tags for different datastore requests. The tags can be passed using 2 mechanisms:

  1. Instance Level tags.
  2. Request Level tags.
  • RequestOptions is the proto that holds all the instance and request level tags and is a part of all request protos.
  • DatastoreOptions allows the ability to set the instance level tags using setRequestTags. Any operation executed via this Datastore client automatically includes these global request tags in the outbound RPC request payload.
  • RequestOptionsHelper an internal utility that combines instance-level tags from DatastoreOptions with any request-level RequestOptions protobuf message before building the wire request.
  • DatastoreExecutionOptions is a holder object for all different options like ExplainOptions, RequestOptions and ReadOption.
  • Overloaded versions for taking in the DatastoreExecutionOptions for each of the following operations:
    • put
    • get
    • fetch
    • delete
    • newTransaction
    • commit
    • rollback
    • allocateId
    • reserveIds
    • runQuery
    • runAggregationQuery
  • Each of these overloaded versions copy the request tags into the request protos.

@rahulmane-goog rahulmane-goog requested review from a team as code owners July 13, 2026 13:26

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request introduces support for passing and merging RequestOptions (such as request tags) in Datastore queries and aggregation queries, allowing both instance-level and request-level tags to be propagated. The feedback highlights a critical issue where instance-level tags are ignored when query-level RequestOptions are not explicitly provided in QueryResultsImpl and AggregationQueryRequestProtoPreparer. Additionally, the reviewer suggests simplifying the varargs withRequestTags overload in Datastore by delegating to the List version, and adding a test case to verify that instance-level tags are correctly populated and sent with queries.

@rahulmane-goog rahulmane-goog force-pushed the feat-datastore-request-tags branch from f124116 to aab1fd3 Compare July 13, 2026 13:43

@rahulmane-goog rahulmane-goog left a comment

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Please review

@lqiu96 lqiu96 added the kokoro:force-run Add this label to force Kokoro to re-run the tests. label Jul 13, 2026
@yoshi-kokoro yoshi-kokoro removed the kokoro:force-run Add this label to force Kokoro to re-run the tests. label Jul 13, 2026
@jinseopkim0

Copy link
Copy Markdown
Contributor

ci / lint is failing. Could you please take a look?

@rahulmane-goog

Copy link
Copy Markdown
Author

ci / lint is failing. Could you please take a look?

Fixed

@rahulmane-goog rahulmane-goog force-pushed the feat-datastore-request-tags branch 2 times, most recently from ae79a99 to d61b477 Compare July 16, 2026 09:46
@rahulmane-goog rahulmane-goog force-pushed the feat-datastore-request-tags branch from d61b477 to 75e872b Compare July 16, 2026 10:12
*/
@BetaApi
Transaction newTransaction(
TransactionOptions options, DatastoreExecutionOptions executionOptions);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks for being open for using DatastoreExecutionOptions. IIRC, the original commits only needed RequestOptions for run and runAggregation, right?

Do all the other RPCs also need RequestOptions functionality?

* @param requestTags the list of request tags to set
* @return the builder object
*/
public Builder setRequestTags(ImmutableList<String> requestTags) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

nit: Can the parameter be of List to be as general as possible?

We can copy the contents over to an immutablelist ourselves to ensure they don't change.

Comment on lines +158 to +160
ExplainOptions explainOptions,
List<ReadOption> readOptions,
RequestOptions requestOptions) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

nit: We can probably replace these three params with DatastoreExecutionOptions and assign the vars from there

this.explainOptions = datastoreExecutionOptions.getExplainOptions()

Comment on lines +197 to +208
public static <Q extends Query<?>> QueryConfig<Q> create(
Q query,
ExplainOptions explainOptions,
List<ReadOption> readOptions,
RequestOptions requestOptions) {
return QueryConfig.<Q>newBuilder()
.setQuery(query)
.setExplainOptions(explainOptions)
.setReadOptions(readOptions)
.setRequestOptions(requestOptions)
.build();
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

nit: Do we need to expose this variant of create if we have:

createWithExecutionOptions(Q query, DatastoreExecutionOptions executionOptions) {?

Can we just have the call this by building the DatastoreExecutionOptions with the required options?

Comment on lines +243 to +256
public Builder<Q> setReadOptions(List<ReadOption> readOptions) {
this.readOptions = readOptions;
return this;
}

public Builder<Q> setExplainOptions(ExplainOptions explainOptions) {
this.explainOptions = explainOptions;
return this;
}

public Builder<Q> setRequestOptions(RequestOptions requestOptions) {
this.requestOptions = requestOptions;
return this;
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

nit: Same here, can the caller just call something like setDatastoreExecutionOptions which has all the required options?

Comment on lines +120 to +128
public Builder setReadOptions(ReadOption... readOptions) {
this.readOptions = readOptions != null ? Arrays.asList(readOptions) : Collections.emptyList();
return this;
}

public Builder setReadOptions(List<ReadOption> readOptions) {
this.readOptions = readOptions != null ? readOptions : Collections.emptyList();
return this;
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

(I may have asked this earlier, but forgot)

What is the need to expose both the varargs and List options in Datastore? Can we only expose the List<?> option for users to pass in? For existing methods that have varargs, we can just pack it into a list and set it here

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants