Skip to content

Conversation

@dandavison
Copy link
Contributor

@dandavison dandavison commented Dec 10, 2025

Implement standalone activity ListActivityExecutions and CountActivityExecutions.


Note

Introduce List/Count ActivityExecutions for standalone activities with queryable search attributes and supporting validation/mapping.

  • Frontend:
    • Implement ListActivityExecutions and CountActivityExecutions using chasm.ListExecutions/CountExecutions; build ActivityExecutionListInfo and grouped counts; paging support.
    • Refactor start-request validation into frontendHandler.validateAndPopulateStartRequest and validateAndNormalizeStartActivityExecutionRequest; add SA unaliasing/validation.
  • Activity Component:
    • Add visibility SAs (ActivityType, ActivityStatus, ActivityTaskQueue) and implement VisibilitySearchAttributesProvider via SearchAttributes.
    • Extract InternalStatusToAPIStatus and run-state mapping; use in buildActivityExecutionInfo.
  • Library/Registration:
    • Register component with declared search attributes in library.go.
  • Visibility Query Resolution:
    • Map ActivityIdWorkflowId as a fallback in resolver; add ActivityID constant in sadefs/constants.go.
  • Tests:
    • Add comprehensive tests for listing, counting (including grouping and custom SAs), and helpers; update validator tests to new validation entry points.

Written by Cursor Bugbot for commit 74c4fa6. This will update automatically on new commits. Configure here.

@dandavison dandavison force-pushed the saa-visibility branch 2 times, most recently from 601fb05 to 65cb249 Compare December 11, 2025 02:21
@dandavison dandavison changed the title Standalone Activity ListActivityExecutions Standalone Activity List and Count ActivityExecutions Dec 11, 2025
@dandavison dandavison force-pushed the saa-visibility branch 2 times, most recently from e349308 to dbdead0 Compare December 11, 2025 20:26
@dandavison dandavison marked this pull request as ready for review December 11, 2025 20:26
@dandavison dandavison requested review from a team as code owners December 11, 2025 20:26
const (
ActivityTypeSAAlias = "ActivityType"
ActivityStatusSAAlias = "ActivityStatus"
ActivityTaskQueueSAAlias = "ActivityTaskQueue"
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
ActivityTaskQueueSAAlias = "ActivityTaskQueue"
TaskQueueSAAlias = "TaskQueue"

Copy link
Member

Choose a reason for hiding this comment

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

Same here, it's just task queue.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Discussed offline, we decided to keep this as-is for now. Other work will address.

"google.golang.org/protobuf/types/known/durationpb"
"google.golang.org/protobuf/types/known/timestamppb"
)

const (
ActivityTypeSAAlias = "ActivityType"
ActivityStatusSAAlias = "ActivityStatus"
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
ActivityStatusSAAlias = "ActivityStatus"
ActivityStatusSAAlias = "ExecutionStatus"

Copy link
Member

Choose a reason for hiding this comment

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

Use the same non-qualified name as workflows.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Should I also ignore this comment and leave it as-is, as we have done for "ActivityTaskQueue"?

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've left this as "ActivityStatus" for now, pending advice (I know there were some discussions in progress relevant to this).

Comment on lines 35 to 44
ActivityTypeSearchAttribute = chasm.NewSearchAttributeKeyword(ActivityTypeSAAlias, chasm.SearchAttributeFieldKeyword01)
ActivityStatusSearchAttribute = chasm.NewSearchAttributeKeyword(ActivityStatusSAAlias, chasm.SearchAttributeFieldLowCardinalityKeyword01)
ActivityTaskQueueSearchAttribute = chasm.NewSearchAttributeKeyword(ActivityTaskQueueSAAlias, chasm.SearchAttributeFieldKeyword02)
Copy link
Member

Choose a reason for hiding this comment

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

I would be totally okay if we didn't stutter here and omitted the Activity prefix from these variables. We're already in the activity package.

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

if err != nil {
return nil, err
}
ctx = chasm.NewVisibilityManagerContext(ctx, h.visibilityManager)
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 something that we expect to be done in an interceptor. Please coordinate with @awln-temporal @lina-temporal and @rodrigozhou on this.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Is this blocking?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

OK I see the interceptor was added on main. I've rebased standalone-activity on main and rebased this PR on standalone-activity and got rid of this.

@@ -238,6 +325,21 @@ func (h *frontendHandler) validateAndPopulateStartRequest(
}
applyActivityOptionsToStartRequest(opts, req)

// TODO: Unalias for validation, then restore aliased SA for CHASM visibility storage. The
// validator requires unaliased format but CHASM visibility expects aliased format.
originalSA := req.SearchAttributes
Copy link
Member

Choose a reason for hiding this comment

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

I would make validateAndNormalizeStartActivityExecutionRequest a method of the handler and unalias in there. Seems cleaner than mutating the request twice.

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.

@@ -38,6 +38,12 @@ func ResolveSearchAttributeAlias(
return sadefs.WorkflowID, saType, nil
}

// Handle ActivityId → WorkflowID transformation for standalone activities
Copy link
Member

Choose a reason for hiding this comment

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

Visibility team should fix the need to hardcode here eventually. Add a TODO.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added TODO

@@ -59,6 +59,8 @@ const (
// any other custom search attribute.
ScheduleID = "ScheduleId"

ActivityId = "ActivityId"
Copy link
Member

Choose a reason for hiding this comment

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

Same here, add a TODO to remove this hardcoded constant.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added TODO

customSAName := "ActivityCustomKeyword"
customSAValue := "custom-sa-test-value"

_, err := s.OperatorClient().AddSearchAttributes(ctx, &operatorservice.AddSearchAttributesRequest{
Copy link
Member

Choose a reason for hiding this comment

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

I think there's a set of custom search attributes already defined for all functional tests.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks, using the predefined custom SAs

})

t.Run("QueryByActivityStatus", func(t *testing.T) {
verifyListQuery(t, fmt.Sprintf("ActivityStatus = 'Scheduled' AND ActivityType = '%s'", activityType))
Copy link
Member

Choose a reason for hiding this comment

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

What's Scheduled? It's supposed Running as we have for ExecutionStatus for workflows (case sensitive?)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks, fixed

Comment on lines 1316 to 1327
s.Equal(activityID, exec.GetActivityId())
s.Equal(runID, exec.GetRunId())
s.Equal(activityType, exec.GetActivityType().GetName())
s.Equal(enumspb.ACTIVITY_EXECUTION_STATUS_RUNNING, exec.GetStatus())
s.NotNil(exec.GetScheduleTime())
Copy link
Member

Choose a reason for hiding this comment

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

Make sure you cover all of the fields of ActivityExecutionListInfo in this test.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

All the fields are tested

@dandavison dandavison force-pushed the saa-visibility branch 3 times, most recently from afa1675 to 973dc71 Compare December 16, 2025 03:29
@dandavison dandavison requested a review from bergundy December 16, 2025 03:33
}

// validateAndNormalizeStartActivityExecutionRequest validates and normalizes the standalone
// activity specific attributes. Note that this method mutates the input params; the caller must
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: differentiate standalone activity "chasm" search attributes vs user defined custom search attributes.

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


// Handle ActivityId → WorkflowID transformation for standalone activities.
// TODO: Remove this hardcoded transformation.
if name == sadefs.ActivityID {
Copy link
Contributor

Choose a reason for hiding this comment

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

Depending on which PR gets landed first, we'll need a follow up here to use the RegistrableComponent BusinessID option: #8803.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks, added the PR to the TODO comment.

return nil
}

func validateAndNormalizeSearchAttributes(
Copy link
Contributor

Choose a reason for hiding this comment

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

this pattern will probably be common for most archetypes that support custom search attributes, might be worth moving to a common shared func in the chasm package, but not blocking.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks, I added a note

@dandavison dandavison merged commit 0247cf0 into standalone-activity Dec 17, 2025
92 of 98 checks passed
@dandavison dandavison deleted the saa-visibility branch December 17, 2025 19:31
dandavison added a commit that referenced this pull request Dec 19, 2025
Implement standalone activity ListActivityExecutions and CountActivityExecutions.
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