Skip to content

(feat): add support for default query handler #1639

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

Merged
merged 5 commits into from
Mar 10, 2025
Merged

Conversation

THardy98
Copy link
Contributor

@THardy98 THardy98 commented Mar 6, 2025

Added support for to register a default query handler - a handler for queries that do not have registered query names/handlers.

  1. Part of [Feature Request] Support dynamic workflows, activities, signals, queries, and updates #1015

  2. How was this tested:
    Added small integration tests.

  3. Any docs updates needed?
    Maybe

@THardy98 THardy98 requested a review from a team as a code owner March 6, 2025 00:12
const activator = assertInWorkflowContext(
'Workflow.setDefaultQueryHandler(...) may only be used from a Workflow Execution.'
);
if (typeof handler === 'function') {
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: You can combine the if and else if branches here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

let fn = this.queryHandlers.get(queryName)?.handler;
// Fallback to default query handler if no handler is registered.
if (fn === undefined) {
fn = this.defaultQueryHandler;
Copy link
Contributor

Choose a reason for hiding this comment

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

The default query handler will need an extra argument, the first one, that indicates the name of the query being called. See signalWorkflowNextHandler().

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed, improved the test to catch this case. Thanks

Copy link
Contributor

@mjameswh mjameswh left a comment

Choose a reason for hiding this comment

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

The default query handler needs the name of the incoming query, just like we do for the default signal handler.

That's the only blocking change.

@THardy98 THardy98 requested a review from mjameswh March 7, 2025 19:52
/**
* A handler function accepting query calls for non-registered query names.
*/
export type DefaultQueryHandler = (queryName: string, ...args: any[]) => any;
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: That should be unknown rather than any (both occurrences).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

// Fallback to default query handler if no handler is registered.
if (fn === undefined && this.defaultQueryHandler !== undefined) {
// Use non-null assertion because Typescript can't tell that defaultQueryHandler cannot be undefined here.
fn = (...args) => this.defaultQueryHandler!(queryName, ...args);
Copy link
Contributor

Choose a reason for hiding this comment

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

TS is technically right: even though you just checked that this.defaultQueryHandler is not undefined, you are then using that field inside a function call; there is no guarantee that this.defaultQueryHandler will still be valid by the time fn gets called. Well, we know it will, but the compiler can't figure this out.

You can avoid the TS error without a non-null assertion by copying this.defaultQueryHandler to a temporary variable inside the if block, or by using this.defaultQueryHandler.bind(...) instead:

Suggested change
fn = (...args) => this.defaultQueryHandler!(queryName, ...args);
fn = this.defaultQueryHandler.bind(this, queryName);

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

Copy link
Contributor

@mjameswh mjameswh left a comment

Choose a reason for hiding this comment

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

Please address my two minor suggestions before merging.

@THardy98 THardy98 merged commit 4155dad into main Mar 10, 2025
23 checks passed
@THardy98 THardy98 deleted the default-queries branch March 10, 2025 17:25
@THardy98 THardy98 changed the title add default query handler (feat): add support for default query handler Mar 31, 2025
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.

2 participants