Skip to content

Conversation

natemort
Copy link
Member

@natemort natemort commented Sep 15, 2025

In order to use activity functions within a Workflow we need to have a very explicit name for the function that we can determine without the registry, as the activity may not even be present within the same registry as the workflow. Remove the concept of aliases, and mandate a decorator on all Activity functions.

For ease of use, continue to support the decorator via the registry to both register and decorate the activity at the same time.

In addition, rather than simply storing the activity function or setting attributes on it to track that it's registered, introduce a wrapping Callable. Within the context of a Workflow we can reinterpret invocations of the activity function as the execution of the activity itself.

What changed?

  • Require activity functions to use a decorator so that they're always explicitly named
  • Add support for Activities being defined on a Class or interface
  • Add support for combining Registry objects
  • Wrap Activity functions so that they can be used within Workflows
  • Use __qualname__ instead of __name__ for activity functions. This is the name of the function relative to the module root, so it includes the Class name for activities that are methods. It seems more intuitive, although if the annotated functions are deeply nested their names may not be coherent.

Why?

  • Better support Activity usage in workflows

How did you test it?

  • Unit tests

Potential risks

Release notes

Documentation Changes

@natemort natemort force-pushed the activity_definition branch 2 times, most recently from 868b5d0 to 1735a9b Compare September 15, 2025 20:12
In order to use activity functions within a Workflow we need to have a very explicit name for the function that we can determine without the registry, as the activity may not even be present within the same registry as the workflow. Remove the concept of aliases, and mandate a decorator on all Activity functions.

For ease of use, continue to support the decorator via the registry to both register and decorate the activity at the same time.

In addition, rather than simply storing the activity function or setting attributes on it to track that it's registered, introduce a wrapping Callable. Within the context of a Workflow we can reinterpret invocations of the activity function as the execution of the activity itself.

Signed-off-by: Nate Mortensen <natemort@uber.com>
type_hint: Type | None
default_value: Any | None

class ExecutionStrategy(Enum):
Copy link
Member

Choose a reason for hiding this comment

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

nit: naming, are we going to have more than 2 types of enum here? if not, perhaps a naming of isAsync might be more descriptive here.

Copy link
Member Author

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 chance we might add multiprocessing support in the future.

name = opts["name"]

strategy = ExecutionStrategy.THREAD_POOL
if inspect.iscoroutinefunction(fn) or inspect.iscoroutinefunction(fn.__call__): # type: ignore
Copy link
Member

Choose a reason for hiding this comment

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

if fn is enforced as a callable, what's the difference between those two if conditions?

Copy link
Member Author

Choose a reason for hiding this comment

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

It covers some really weird edge cases. This PR to CPython actually has good examples: https://github.com/python/cpython/pull/99247/files

        class Cl:
            async def __call__(self):
                pass

        self.assertFalse(inspect.iscoroutinefunction(Cl))
        # instances with async def __call__ are NOT recognised.
        self.assertFalse(inspect.iscoroutinefunction(Cl()))

I don't really know why it works this way, but it does. The only likely scenario for someone to run into an issue with this is if they have other decorators on the function.

@natemort natemort merged commit e361295 into cadence-workflow:main Sep 16, 2025
5 checks passed
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.

3 participants