Question

It seems that according to swf-docs the following code:

@Workflow
@WorkflowRegistrationOptions(
   defaultExecutionStartToCloseTimeoutSeconds = 60,
   defaultTaskStartToCloseTimeoutSeconds = 10)
public interface MyWorkflow
{
    @Execute(version = "1.0")
    Promise<String> startMyWF(int a, String b);
}    

Should generate MyWorkflowClientExternal that returns a Promise<String>; i.e.:

Promise<String> startMyWF(int a, String b);

However, instead a void method is generated for both MyWorkflowClientExternal and MyWorkflowClientExternalImpl:

void startMyWF(int a, String b) ...

The internal client MyWorkflowClient and MyWorkflowClientImpl does return the Promise object as expected:

Promise<String> startMyWF(int a, String b);

I would like to use ExternalClient; but it does not seem to return the Promise object. I would very much appreciate clarifications.

Thank you.

Was it helpful?

Solution

I posted this question on the AWS-SWF developer forum; and @maxim-fateev has kindly pointed several approaches:

The return value of a workflow is very useful for child workflows because they are modeled as asynchronous calls. For standalone workflows, you can use one of the following options to retrieve the results:

1) Get it from the workflow history using SWF API GetWorkflowExecutionHistory (the result is in the WorkflowExecutionCompleted event). You can also inspect the history using the SWF console.

2) Design your workflow to put the result somewhere, for example you can add an activity at the end to put the result in a store and have the application look there periodically.

3) Host an activity in the program that starts the workflow execution. The workflow starter program now becomes part of the workflow and the activity it hosts can be passed the result of the workflow.

You may use the first option in manually operated tools. However, it is not recommended as a general mechanism for applications to retrieve workflow results because it effectively requires you to poll SWF to check for workflow completion and goes against our long polling design.

I went with the approach #2; here is the gist of it (if you think there is a better way; please do let me know).

Created NotificationActivityImpl:

public class NotificationActivitiesImpl implements NotificationActivities {

    private Object notification;

    public NotificationActivitiesImpl() {
        this.notification = null;
    }

    @Override
    public void notify(Object obj) {
        this.notification = obj;
    }

    /**
     * @return notification (will block until it is available)
     */
    @Override
    public Object getNotification() {
        while (notification == null ){
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        return notification;
    }
}

In the WorkflowImpl added:

notificationClient.notify(obj) // obj that want to pass back to your app

In the App (which starts the workflow; and NotificationAcitivityWorker) added the following:

workflowWorker.start();
notificationWorker.start();
NotificationActivitiesImpl notificationImpl = (NotificationActivitiesImpl) notificationWorker.getActivitiesImplementations().iterator().next();
Object notification = notificationImpl.getNotification();
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top