How to customize workflow type name?

Hi Folks

We’ve a use-case where we might create workflows from DDL. AFAIK, workflowTypes are named after the main method for that workflow. Given our DDL use-case, we would like to change the type to a customized name. Is it possible?
We would like to query workflows and thinking of using this customized type name for filtering, hence the need for customized name.

Thanks in advance for your support.

Use worker.RegisterWorkflowWithOptions:

	w.RegisterWorkflowWithOptions(
                 <workflowFn>, workflow.RegisterOptions{Name: <name>})
1 Like

Any plans to do similar thing in Java SDK? I was curious about that too and it looks like that in Java it is only possible to set WF name by using ‘name’ attribute on @WorkflowMethod, so it is static.


…temporal-sdk-1.0.3-sources.jar!/io/temporal/internal/sync/POJOWorkflowMethodMetadata.java:44

What would be the semantic of calling such workflow in case of Java? Should we pass the workflow type name into Workflow.newChildWorkflowStub call as an option?

Not sure, just thinking in terms of parity among SDKs, and this seems to me as one of ways change propagation can happen - one is to register WF with different queues, another is to manipulate WF name, I have use case that seems to call for a dynamic WF that internally maintains an FSM (Final State Machine), there would be some variations of FSM-s at the time of workflow initiation, and manipulating name seems like a way to make that visible. Again, I might be wrong and there are better ways to do it. Just thoughts.

This is an interesting topic. Longer term we plan to provide direct support for workflows that implement DSL support. The basic idea would be that the workflow worker would be registered as a special DSL workflow and each DSL document instance would be treated as a separate workflow type automatically.

Hi, Do we have workflow type name customization available for Java SDK now?

Do you have any plans to create something similar to this in the python SDK? We have a generic workflow deployed in different workers with a different set of activities. Right now, we route to one version or another one based on the queue name and that is working but in the UI we see the name of the generic worklow and that is not very useful as we have some high level workflows calling different implementations of the generic one and it is difficult to see this in the UI.

Being able to specify different names for the workflow at deployment time (but these are predictable, so we do not need to go all the way there to dynamic workflows) would solve the UI problem. It might also enable us to be more flexible with the queue allocation if we can use the new name to invoke the workflow, but I guess that will depend on how the feature is implemented.

Thanks!

The @workflow.defn decorator can be provided a name if you want to deviate from the default (which is unqualified class name)

But that only allows one name per class, and you cannot change it in a sensible way without modifying the code. I would to be able to define the name when I am configuring the worker as I want to have different names for the same class in different workers.

BTW the Temporal Java SDK supports DynamicWorkflow and DynamicActivity that solve this problem holistically.

These are also supported by the python SDK but they are a big hammer just to be able to change the workflow name at registration time. The documentation itself warns you about relying on dynamic workflows as your primary strategy.

Python supports dynamic workflows/activities as well if this is the route you want to take but I saw above that you don’t want to “go all the way there”. Often people don’t use different workflow type names for the same workflow, but rather use differing input values to differentiate what the workflow should do, and use different search attributes to provide different things (like a “Name” search attribute).

But if you had to create dynamic classes in Python with different decorators you probably could with something like:

@workflow.run
async def run(self) -> None:
    return await super(self.__class__, self).run()

MyNewWorkflowClass = workflow.defn("my-dyn-name")(type("MyNewWorkflowClass", (MyOrigWorkflowClass,), {"run": run}))

But this is untested (just hand-typed here in forum) and not really recommended. We could consider an issue to have a Go-like solution where you can set a custom name at registration time instead of declaration time if it’s really needed. It just hasn’t been traditionally needed (only set at registration time on Go because Go doesn’t have decorators/annotations/attributes).

I spent a few hours trying tricks like the above before, but the SDK has a lot of protections in place to avoid this magic to work. For example, it is checking that the run method has been defined in the same class as the one where the defn annotation has been set. For your particular example, it will fail with something like like local methods are not allowed. And different similar tricks failed with some other error messages. The SDK is really well protected against most of these dynamic types. If there was a hole in the protections I was unable to find it.

What finally made for us is just to create subclasses of our standard workflow where the run method is delegating to super (as in your example above). It would be less boilerplate code if you were to remove the restriction that you need to override the run method in every subclass. But I guess that you introduced that restriction for a reason.

Yes, this is by intention, we don’t want workflow entry points in base classes (and we want to avoid diamond problem of possibly having multiple). When inheriting, a run method has to be present on the final class (even if it delegates to super).

Yes, this is intentional. The same thing with requiring the workflow.defn on the final class in the hierarchy too. We’ve found hiding the run method in the base class to be difficult for workflow readers especially in multiple inheritance languages. The different inheritance rules are covered in [bullets on the README](GitHub - temporalio/sdk-python: Temporal Python SDK as well as on the API. We do allow signal/query methods to be on base classes without forcing override.