From 699ef4b540ca499f22f2c4e61711f8d66dbbdac1 Mon Sep 17 00:00:00 2001 From: Quinn Klassen Date: Thu, 17 Oct 2024 16:52:12 -0700 Subject: [PATCH 1/5] Add @WorkflowInit docs for Java --- docs/develop/java/message-passing.mdx | 51 +++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/docs/develop/java/message-passing.mdx b/docs/develop/java/message-passing.mdx index 1279f515f5..9bbc56353d 100644 --- a/docs/develop/java/message-passing.mdx +++ b/docs/develop/java/message-passing.mdx @@ -508,6 +508,57 @@ public interface MyWorkflow { See [Finishing handlers before the Workflow completes](/encyclopedia/workflow-message-passing#finishing-message-handlers) for more information. +### Use `@WorkflowInit` to operate on Workflow input before any handler executes + +Normally, your Workflows constructor won't have any parameters. +However, if you use the `@WorkflowInit` annotation on your constructor, you can give it the same [Workflow parameters](/develop/java/core-application#workflow-parameters) as your `@WorkflowMethod`. +The SDK will then ensure that your constructor receives the Workflow input arguments that the [Client sent](/develop/python/temporal-clients#start-workflow-execution). +(The Workflow input arguments are also passed to your `@WorkflowMethod` method -- that always happens, whether or not you use the `@WorkflowInit` annotation.) +This is useful if you have message handlers that need access to workflow input: see [Initializing the Workflow first](/encyclopedia/workflow-message-passing#workflow-initializers). + +Here's an example. +Notice that the constructor and `getGreeting` must have the same parameters: + +```java +public class GreetingExample { + @WorkflowInterface + public interface GreetingWorkflow { + @WorkflowMethod + String getGreeting(String input); + + @UpdateMethod + boolean checkTitleValidity(); + } + + public static class GreetingWorkflowImpl implements GreetingWorkflow { + private final String nameWithTitle; + private final String titleHasBeenChecked; + ... + // Note the annotation is on a public constructor + @WorkflowInit + public GreetingWorkflowImpl(String input) { + this.nameWithTitle = "Sir " + input; + this.titleHasBeenChecked = false; + } + + @Override + public String getGreeting(String input) { + Workflow.await(() -> titleHasBeenChecked) + return "Hello " + nameWithTitle; + } + + @Override + public boolean checkTitleValidity() { + // 👉 The handler is now guaranteed to see the workflow input + // after it has been processed by the constructor. + boolean isValid = activity.checkTitleValidity(nameWithTitle); + titleHasBeenChecked = true; + return isValid; + } + } +} +``` + ### Use locks to prevent concurrent handler execution {#control-handler-concurrency} Concurrent processes can interact in unpredictable ways. From a4c36a70cb5471d25191cdcab2e431564e869ae9 Mon Sep 17 00:00:00 2001 From: Erica Sadun <156466156+fairlydurable@users.noreply.github.com> Date: Mon, 28 Oct 2024 11:12:23 -0600 Subject: [PATCH 2/5] Update docs/develop/java/message-passing.mdx --- docs/develop/java/message-passing.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/develop/java/message-passing.mdx b/docs/develop/java/message-passing.mdx index 9bbc56353d..ea47bdf11e 100644 --- a/docs/develop/java/message-passing.mdx +++ b/docs/develop/java/message-passing.mdx @@ -514,7 +514,7 @@ Normally, your Workflows constructor won't have any parameters. However, if you use the `@WorkflowInit` annotation on your constructor, you can give it the same [Workflow parameters](/develop/java/core-application#workflow-parameters) as your `@WorkflowMethod`. The SDK will then ensure that your constructor receives the Workflow input arguments that the [Client sent](/develop/python/temporal-clients#start-workflow-execution). (The Workflow input arguments are also passed to your `@WorkflowMethod` method -- that always happens, whether or not you use the `@WorkflowInit` annotation.) -This is useful if you have message handlers that need access to workflow input: see [Initializing the Workflow first](/encyclopedia/workflow-message-passing#workflow-initializers). +This is useful if you have message handlers that need access to Workflow input: see [Initializing the Workflow first](/encyclopedia/workflow-message-passing#workflow-initializers). Here's an example. Notice that the constructor and `getGreeting` must have the same parameters: From 0d8481fe4dde7225dc3911a57f2c30980529b728 Mon Sep 17 00:00:00 2001 From: Erica Sadun <156466156+fairlydurable@users.noreply.github.com> Date: Mon, 28 Oct 2024 11:12:43 -0600 Subject: [PATCH 3/5] Update docs/develop/java/message-passing.mdx --- docs/develop/java/message-passing.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/develop/java/message-passing.mdx b/docs/develop/java/message-passing.mdx index ea47bdf11e..0833d6dff8 100644 --- a/docs/develop/java/message-passing.mdx +++ b/docs/develop/java/message-passing.mdx @@ -513,7 +513,7 @@ See [Finishing handlers before the Workflow completes](/encyclopedia/workflow-me Normally, your Workflows constructor won't have any parameters. However, if you use the `@WorkflowInit` annotation on your constructor, you can give it the same [Workflow parameters](/develop/java/core-application#workflow-parameters) as your `@WorkflowMethod`. The SDK will then ensure that your constructor receives the Workflow input arguments that the [Client sent](/develop/python/temporal-clients#start-workflow-execution). -(The Workflow input arguments are also passed to your `@WorkflowMethod` method -- that always happens, whether or not you use the `@WorkflowInit` annotation.) +The Workflow input arguments are also passed to your `@WorkflowMethod` method -- that always happens, whether or not you use the `@WorkflowInit` annotation. This is useful if you have message handlers that need access to Workflow input: see [Initializing the Workflow first](/encyclopedia/workflow-message-passing#workflow-initializers). Here's an example. From f9d8ae1575e948d14fc510fc196b697919c5f18a Mon Sep 17 00:00:00 2001 From: Erica Sadun <156466156+fairlydurable@users.noreply.github.com> Date: Mon, 28 Oct 2024 11:12:59 -0600 Subject: [PATCH 4/5] Update docs/develop/java/message-passing.mdx --- docs/develop/java/message-passing.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/develop/java/message-passing.mdx b/docs/develop/java/message-passing.mdx index 0833d6dff8..8553a6d963 100644 --- a/docs/develop/java/message-passing.mdx +++ b/docs/develop/java/message-passing.mdx @@ -514,7 +514,7 @@ Normally, your Workflows constructor won't have any parameters. However, if you use the `@WorkflowInit` annotation on your constructor, you can give it the same [Workflow parameters](/develop/java/core-application#workflow-parameters) as your `@WorkflowMethod`. The SDK will then ensure that your constructor receives the Workflow input arguments that the [Client sent](/develop/python/temporal-clients#start-workflow-execution). The Workflow input arguments are also passed to your `@WorkflowMethod` method -- that always happens, whether or not you use the `@WorkflowInit` annotation. -This is useful if you have message handlers that need access to Workflow input: see [Initializing the Workflow first](/encyclopedia/workflow-message-passing#workflow-initializers). +This is useful if you have message handlers that need access to Workflow input: see [Initializing the Workflow first](/encyclopedia/workflow-message-passing#workflow-initializers. Here's an example. Notice that the constructor and `getGreeting` must have the same parameters: From 662382099cd165d4e1ee9f62ddfc4ef52d5ae2a5 Mon Sep 17 00:00:00 2001 From: Erica Sadun <156466156+fairlydurable@users.noreply.github.com> Date: Wed, 6 Nov 2024 15:02:44 -0700 Subject: [PATCH 5/5] Update docs/develop/java/message-passing.mdx --- docs/develop/java/message-passing.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/develop/java/message-passing.mdx b/docs/develop/java/message-passing.mdx index b478432d2c..dc1f3c112d 100644 --- a/docs/develop/java/message-passing.mdx +++ b/docs/develop/java/message-passing.mdx @@ -512,7 +512,7 @@ Normally, your Workflows constructor won't have any parameters. However, if you use the `@WorkflowInit` annotation on your constructor, you can give it the same [Workflow parameters](/develop/java/core-application#workflow-parameters) as your `@WorkflowMethod`. The SDK will then ensure that your constructor receives the Workflow input arguments that the [Client sent](/develop/python/temporal-clients#start-workflow-execution). The Workflow input arguments are also passed to your `@WorkflowMethod` method -- that always happens, whether or not you use the `@WorkflowInit` annotation. -This is useful if you have message handlers that need access to Workflow input: see [Initializing the Workflow first](/encyclopedia/workflow-message-passing#workflow-initializers. +This is useful if you have message handlers that need access to Workflow input: see [Initializing the Workflow first](/encyclopedia/workflow-message-passing#workflow-initializers). Here's an example. Notice that the constructor and `getGreeting` must have the same parameters: