Skip to content

Special behaviour for temporal prefixes #1644

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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

THardy98
Copy link
Contributor

@THardy98 THardy98 commented Mar 11, 2025

What was changed

Special behavior handling reserved temporal prefixes. Prevent users from:

  • registering workflows, activities, task queues, signals/updates/queries with a reserved prefix
  • calling default handlers with reserved names
  • calling internal queries without going through interceptors

This change makes the reserved metrics names reserved across all entities (workflows, activities, signals, etc..).


Checklist

Some remaining items:

  • need to reserving prefixes from workflows,
  • waiting for default update handler to be merged to prevent default update handler to be called with reserved names
  1. Closes [Feature Request] Special behavior for Temporal built-in prefixes #1599

  2. How was this tested:
    unit/integration tests

  3. Any docs updates needed?
    I'm not sure.

@THardy98 THardy98 requested a review from a team as a code owner March 11, 2025 02:12
@THardy98
Copy link
Contributor Author

In this change, users are prevented from registering signals/updates/queries with reserved names from the handler.

Users can still defineQuery, defineSignal, defineUpdate that have reserved names. The reason for this is because we use defineQuery to create the reserved queries ourselves.

Alternatively, we can do the blocking in define<X> and create our internal queries/signals/updates using internal functions. Or we can do both (blocking in the define and the handler). I picked one because it seemed sufficient.

… test needs to be fixed, need to add behaviour reserving prefixes from workflows, and waiting for default update to be merged to add behaviour preventing default update handler to be called with reserved names
@THardy98 THardy98 force-pushed the handle_temporal_builtin_prefixes branch from 8170bc5 to 5f5103a Compare March 17, 2025 20:53
@THardy98 THardy98 changed the title [WIP] Special behaviour for temporal prefixes Special behaviour for temporal prefixes Mar 20, 2025
@THardy98 THardy98 changed the title Special behaviour for temporal prefixes [WIP] Special behaviour for temporal prefixes Mar 20, 2025
@THardy98 THardy98 changed the title [WIP] Special behaviour for temporal prefixes Special behaviour for temporal prefixes Mar 25, 2025
@THardy98
Copy link
Contributor Author

this is blocked on #1640 so we can handle the same prefix cases for updates as well

@@ -2528,3 +2534,83 @@ test('Signals/Updates/Activities/Timers - Trace promises completion order - 1.11
);
}
});

test('Default query handler fail activations with reserved names - workflowWithDefaultHandlers', async (t) => {
Copy link
Contributor

Choose a reason for hiding this comment

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

Why did you fallback to unit tests for default handlers?

@@ -619,6 +625,8 @@ export class Activator implements ActivationHandler {
protected queryWorkflowNextHandler({ queryName, args }: QueryInput): Promise<unknown> {
let fn = this.queryHandlers.get(queryName)?.handler;
if (fn === undefined && this.defaultQueryHandler !== undefined) {
// Do not call default query handler with reserved query name.
throwIfReservedName('query', queryName);
Copy link
Contributor

Choose a reason for hiding this comment

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

I think we should not be throwing this way here. Code below is clearly designed to make sure that we are not throwing synchronously. Also, UI expects that we'll answer back with a list of accepted query types.

Actually, I'd just skip the default handler if query name is reserved. We'll still throw below, but we'll then be going the same code path as if that wasn't a reserved type name.

@@ -797,6 +816,8 @@ export class Activator implements ActivationHandler {
if (fn) {
return await fn(...args);
} else if (this.defaultSignalHandler) {
// Do not call default signal handler with reserved signal name.
throwIfReservedName('signal', signalName);
Copy link
Contributor

Choose a reason for hiding this comment

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

We definitely shouldn't throw here, as that means that adding reserved signals in the future would make those poison pills for any workers that don't yet know about them if there's a default signal handler registered. In fact, we should simply not enter signalWorkflowNextHandler if that's a reserved name and there is no registered signalHandlers for that name.

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.

[Feature Request] Special behavior for Temporal built-in prefixes
2 participants