Skip to content

feat: Unified activity operator APIs#743

Merged
spkane31 merged 21 commits intomasterfrom
spk/activity-operator-cmds
Apr 28, 2026
Merged

feat: Unified activity operator APIs#743
spkane31 merged 21 commits intomasterfrom
spk/activity-operator-cmds

Conversation

@spkane31
Copy link
Copy Markdown
Contributor

@spkane31 spkane31 commented Mar 24, 2026

What changed?
Add {Pause/Unpause/Reset/Update}ActivityExecution RPCs and corresponding request/response pairs that will target both workflow embedded and standalone activities. These all strictly target a single activity by ID, if a workflow_id is specified on the request the operation targets a workflow activity.

Why?
Unified support for activity operations.

Breaking changes
None

Server PR
Does not break server

@spkane31 spkane31 requested review from a team March 24, 2026 20:04
@spkane31 spkane31 marked this pull request as draft March 24, 2026 20:04
@spkane31 spkane31 changed the title [DO NOT MERGE] Prototype activity operator APIs feat: Unified activity operator APIs Mar 24, 2026
@spkane31 spkane31 marked this pull request as ready for review March 24, 2026 23:08
Copy link
Copy Markdown
Member

@bergundy bergundy left a comment

Choose a reason for hiding this comment

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

The comments I put on the PauseActivityExecution request applies to all of the new APIs.

};
option (temporal.api.protometa.v1.request_header) = {
header: "temporal-resource-id"
value: "workflow:{workflow_id}"
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.

This header is conditional based on whether the API is targeting a workflow or an activity.

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.

See what RespondActivityTaskCompletedById did here.

Comment on lines +1706 to +1710
post: "/namespaces/{namespace}/activities/{activity_id}/pause"
body: "*"
additional_bindings {
post: "/api/v1/namespaces/{namespace}/activities/{activity_id}/pause"
body: "*"
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.

@spkane31 spkane31 requested a review from bergundy March 25, 2026 19:53
Copy link
Copy Markdown
Member

@bergundy bergundy left a comment

Choose a reason for hiding this comment

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

Approved but please do not merge until you have a working server implementation just to be sure that nothing is missed.

string namespace = 1;

// If provided, targets a workflow activity for the given workflow ID.
// If empty, target a standalone activity.
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.

Suggested change
// If empty, target a standalone activity.
// If empty, targets a standalone activity.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixing in all four spots

// If empty, target a standalone activity.
string workflow_id = 2;
// The ID of the activity to target. Must be provided for a standalone activity.
// Mutually exclusive with workflow_activity_type.
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.

Looks like mention of workflow_activity_type in comments is stale -- it doesn't exist in any of them.

Suggested change
// Mutually exclusive with workflow_activity_type.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Also making to all 4 requests

Comment on lines +2038 to +2039
// Resource ID for routing. Contains "workflow:{workflow_id}" for workflow activities or "activity:{activity_id}" for standalone activities.
string resource_id = 9;
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.

Is resource_id something stale that you've moved away from in favor of the multiple business_id logic in the generated history client routing options?

string workflow_id = 2;
// The ID of the activity to target. Must be provided for a standalone activity.
// Mutually exclusive with workflow_activity_type.
string activity_id = 3;
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.

Is activity_id required now that we don't have workflow_activity_type?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yes, updating docs


// Resource ID for routing. Contains "workflow:{workflow_id}" for workflow activities or "activity:{activity_id}" for standalone activities.
string resource_id = 10;
}
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.

Is it a design decision that there's no "reason" for Reset?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

There is not a reason field on the existing ResetActivityRequest so the decision was to be consistent.

Copy link
Copy Markdown
Member

@Sushisource Sushisource left a comment

Choose a reason for hiding this comment

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

Nothing blocking, just a few minor things

string reason = 6;

// Used to de-dupe pause requests.
string request_id = 7;
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.

Why add if message is deprecated?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Deprecated but not going to be removed just yet. I added the request_id to have the same functionality for the legacy and new code paths.


// If set, the activity options will be restored to the defaults.
// Default options are then options activity was created with.
// They are part of the first SCHEDULE event.
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.

Suggested change
// They are part of the first SCHEDULE event.
// They are part of the first schedule event.

The all caps to me implies that it exactly equals some event name, but it doesn't. I'd just lower case it or actually use the full-on event name

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

👍 a few other spots I'll make this change

// * if there are more retries left - the activity will be paused.
// For long-running activities:
// - activities in paused state will send a cancellation with "activity_paused" set to 'true' in response to 'RecordActivityTaskHeartbeat'.
// - The activity should respond to the cancellation accordingly.
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.

A bit more detail on "accordingly" would be nice

Comment on lines +1919 to +1925
// Flags:
//
// 'jitter': the activity will be scheduled at a random time within the jitter duration.
// If the activity currently paused it will be unpaused, unless 'keep_paused' flag is provided.
// 'reset_heartbeats': the activity heartbeat timer and heartbeats will be reset.
// 'keep_paused': if the activity is paused, it will remain paused.
//
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.

IMO no need to re-iterate flag docs from the request message

// If the activity was paused while waiting for retry, it will be scheduled immediately (* see 'jitter' flag).
// Once the activity is unpaused, all timeout timers will be regenerated.
//
// Flags:
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.

Same about not duping flag docs

@spkane31 spkane31 merged commit 4087826 into master Apr 28, 2026
4 checks passed
@spkane31 spkane31 deleted the spk/activity-operator-cmds branch April 28, 2026 20:51
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