Skip to content

Conversation

gow
Copy link
Contributor

@gow gow commented Jul 11, 2025

We decided to support pausing of activities by type with the following options:

  • All: Pause all running and future activities of the given type.
  • Running: Pause just the currently running activities.
  • Future: Pause just the future activities if the given type.

This is to support different options while pausing by activity type.

@gow gow requested review from a team as code owners July 11, 2025 00:15
string reason = 6;

// (-- api-linter: core::0123::resource-annotation=disabled --)
message PauseByType{
Copy link
Member

Choose a reason for hiding this comment

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

Pedantic, but usually there is a space between identifier and open brace

PauseByTypeOption option = 2;
}

enum PauseByTypeOption{
Copy link
Member

Choose a reason for hiding this comment

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

I was under the impression we were considering visibility-like queries for deciding what activities certain actions would affect, is that the case?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is for activity pause/unpause APIs. The primary purpose is to allow someone to pause all activities of a certain type. The current implementation explicitly pauses just the running instances of an activity and doesn't pause any future instances.
Regarding rules & actions - nothing changes. Rules will still use queries and identify the activities (by id) to be paused.

Copy link
Member

Choose a reason for hiding this comment

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

This is for activity pause/unpause APIs

Mentioned in other comment, but this is not applying to unpause that I can see

The primary purpose is to allow someone to pause all activities of a certain type

What if I want to pause all activities regardless of type? In unpause that is a boolean, not here?

The current implementation explicitly pauses just the running instances of an activity and doesn't pause any future instances.

So how can I pause future instances without being forced to provide a type? Or pause all?

We should be consistent here. Why does whether I want my predicate to apply to all or running or future have to do with what that predicate is?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Are we conflating rules and individual activity operations here? My understanding of these individual activity operations is that they operate on specified activity/s. Activities are identified by id or by type in the API input. When identified by id it's implicit that they are currently running activities (so no additional options apply here). When identified by type they could be currently running or the ones started in future. So we need additional options (running, future, all). So actions differ based on how you identify the activity.

So how can I pause future instances without being forced to provide a type?

If we want to do this via activity pause/unpause APIs we can support wildcard * to identify all activities? The question is how do we identify/represent "all activities" in these APIs.

Workflow rules have predicates that are evaluated and automated action is taken. This is were typically actions are independent of predicates.
Let me know if my understanding of how these APIs and rules would be employed is incorrect.

Copy link
Member

@cretz cretz Jul 14, 2025

Choose a reason for hiding this comment

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

My understanding of these individual activity operations is that they operate on specified activity/s.

Why can't I apply activity operations on all activities for a workflow? Why are we limiting to only certain IDs or types?

When identified by id it's implicit that they are currently running activities (so no additional options apply here). When identified by type they could be currently running or the ones started in future.

Regardless of how identified (id, type, all, selector in the future, etc), I should be able to specify an activity state they should apply to.

Can I pause all running activities? Can I pause all future activities? Can I pause all activities regardless of whether future or running?

If we want to do this via activity pause/unpause APIs we can support wildcard * to identify all activities?

No, unpause already has this, a boolean to apply to all. We're strangely inconsistent with ourselves on how to apply something to all activities (or all running or all future). We can become consistent by adding a boolean here if we want for "all" or we can change that one.

PauseByTypeOption option = 2;
}

enum PauseByTypeOption{
Copy link
Member

Choose a reason for hiding this comment

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

Might I want to choose all, running, or future for more than just activity type? For instance, how do I pause all future activities regardless of type? Whether the predicate applies to all, running, or future doesn't seem to relate to the predicate itself.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

These are part of single activity operation APIs (pause/unpause/reset). Pausing all activities within a workflow is under the scope of workflow pause (which is being speced currently).

Copy link
Member

@cretz cretz Jul 11, 2025

Choose a reason for hiding this comment

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

What about only pausing future activities regardless of type? It is confusing to only be able to do some activity pausing via workflow pause. I don't want to pause my workflow, I want to pause activities. I think we need to think about this from a devx/user POV. I want to pause all activities, I want to pause running activities, I want to pause future activities, I want to pause running activities of a certain type, etc etc need to be a cohesive, easy to understand interface. To tell someone half of that is done elsewhere is not good devx.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Agree. All cases you mentioned are covered except being able to specify "all" activity types. Like mentioned above, we can add a wildcard * to allow users to indicate that they want to pause all activities. Thoughts?

Copy link
Member

Choose a reason for hiding this comment

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

Mentioned in other reply, we should be consistent with unpause. Why have a boolean for all there and a special string for all here? And why should I even have to set a type at all if I don't care about type?

PauseByTypeOption option = 2;
}

enum PauseByTypeOption{
Copy link
Member

Choose a reason for hiding this comment

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

Unpause has a concept of type also, does this same concern apply there? Also, unpause has a concept of "all" there too, does this same feature need to apply 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.

No. I'm not planning to support selectively unpausing activity by type. We can add it in the future if needed?

Copy link
Member

Choose a reason for hiding this comment

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

We already support unpausing activity by type today, see the API. So today we support pausing and unpausing activities with the same predicate capabilities. This now makes pause selection different than unpause selection and therefore confusing from a user understanding POV.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I agree about the inconsistency between pause and unpause API. My initial reasoning was that there is no use case to selectively unpause just running, future, all (when unpausing by type). So I left it out. I'll add similar unpause options to unpause API as well.

Copy link
Member

Choose a reason for hiding this comment

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

I'll add similar unpause options to unpause API as well.

👍 Will be interested in what this looks like when done. I think you'll find that the enumerate state of the activity is wholly unrelated to its type and therefore PauseByType doesn't make sense because it doesn't sense to combine the two since they are distinct filters.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I see your point. Added PauseOptionActivityState (open to other name suggestions). Now one can pause/unpause any combination of

  • activity: {id, type, all}
  • activity_state: {running, future, both}

There are some invalid combinations like {activity: id, activity_state: future}. But these will be handled in the API implementation.

Copy link
Member

Choose a reason for hiding this comment

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

This looks great to me!

Copy link
Member

@cretz cretz left a comment

Choose a reason for hiding this comment

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

LGTM, but can we make sure to at least get most of the impl done server side before we merge this? I want to confirm the server can work with these changes and we won't learn something during implementation.

// Reason to pause the activity.
string reason = 6;

// which activities to pause - current, future or both.
Copy link
Contributor

Choose a reason for hiding this comment

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

comment says "which activities to pause" - but previous oneof selector selects which activities to pause.
also what is the interaction between id and activity_state? What does it mean 'future activities by id'?

Copy link
Contributor

Choose a reason for hiding this comment

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

same for "match all". I don't think "match all" and "for all, now and in the future" should coexist...
hm. I think you separated those qualifiers into activity_state after discussion with Chad, but I don't think this is the right idea.

it should be part of "type".
(not going to block on this)

Copy link
Member

@cretz cretz Jul 15, 2025

Choose a reason for hiding this comment

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

IMO they are independent filters and if both are present, both must be satisfied. The other is "which activities", this is "also limit by current state" IMO.

Copy link
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.

I thought we said that we want pause for future activities to be done globally in namespace rules. Surprised to see us adding per-workflow future activity pause.

}

// Pause option activity state is used to specify if we want to pause/unpause just the current activity, or just the future activities or both.
enum PauseOptionActivityState {
Copy link
Member

Choose a reason for hiding this comment

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

Why is this in workflow.proto and not activity.proto?

Copy link
Member

Choose a reason for hiding this comment

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

Or maybe this could be generalized for workflows too? Would we want this for workflow pause?

PAUSE_OPTION_ACTIVITY_STATE_UNSPECIFIED = 0;
PAUSE_OPTION_ACTIVITY_STATE_RUNNING = 1;
PAUSE_OPTION_ACTIVITY_STATE_FUTURE = 2;
PAUSE_OPTION_ACTIVITY_STATE_BOTH = 3;
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
PAUSE_OPTION_ACTIVITY_STATE_BOTH = 3;
PAUSE_OPTION_ACTIVITY_STATE_ANY = 3;

}

// Pause option activity state is used to specify if we want to pause/unpause just the current activity, or just the future activities or both.
enum PauseOptionActivityState {
Copy link
Contributor

Choose a reason for hiding this comment

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

either create acitvity.proto, or add to "common".
Or remove "activity" and change it to "ENTITY" to generalize?

Copy link
Contributor

Choose a reason for hiding this comment

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

why this comment is here...

// If set, the activity will start at a random time within the specified jitter duration.
google.protobuf.Duration jitter = 9;

// which activities to unpause - current, future or both.
Copy link
Member

Choose a reason for hiding this comment

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

Inconsistent with capitalization of comments

// If set, the activity will start at a random time within the specified jitter duration.
google.protobuf.Duration jitter = 9;

// which activities to unpause - current, future or both.
Copy link
Member

Choose a reason for hiding this comment

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

Safe to assume "any" is the default when unspecified? Can you clarify that in comment?

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