Asynchronous execution of workflow operations

Interact with service API of the workflow in asynchronous way

Posted by Automatiko team on June 16, 2021 · 7 mins read

Taking control over how operations are performed from a client side - asynchronously or synchronously

Async or sync way - that's the question

Interacting with a service API might have different needs depending who is calling it or in what context. At the same time not knowing how much time it will take to complete given request might be a problematic for some consumers. That leads to a question how given consumer should invoke the service?

Service could be invoked in blocking way meaning it will wait until the request is processed completely and returns the response. That is usually considered a synchronous way of interacting with a service API. In many case it will be completely fine especially when the response is needed to be available to move forward with business logic. A good example of that is authentication request - it does not make sense to send authentication request and not to wait for the response, as based on the response an action is taken to either let the user into the system or not. So such use case is a perfect fit for synchronous interation.

But this is not always the case - that you need to get the response directly or not have response at all. This is seen more of a asynchronous way of interacting with a service API. With that, client that calls the API can instruct the service that it does not want to wait for processing of the request but wants to know if the request was accepted. Furthermore the client invoking the service can still be interested in the response so response from the service should contain some information what to do to get the response or simply outcome of the work.

This brings us to the feature of Automatiko that is about to be released with 0.6.0 and that is async execution.

Async execution in details

Automatiko allows consumers of the service (one that is built out of the workflow definition) to interact with the API in either synchronous (default) or asynchronous way. To make this decision clients of the API need to set the header to instruct what is the mode to be used. This is actually only required if you want to interact in asynchronous way.

The header that controls this behavior is X-ATK-Mode and the value it expects is async. That will simply return response directly to the caller and make the processing in the background.

Sample request (curl) that instructs the API to run in async mode

  curl -X 'POST' \
    'http://localhost:8080/scripts' \
    -H 'accept: application/json' \
    -H 'Content-Type: application/json' \
    -H 'X-ATK-Mode: async' \
    -d '{
    "lastName": "doe",
    "name": "john"
  }'
Response that is returned when async mode is requested

HTTP/1.1 202 Accepted
Content-Length: 98
Content-Type: application/json

{"id":"18cd32fe-b5cd-4b6c-b862-910f5a0bc410","lastName":"doe","name":"john"}

With that all the work that the business logic requires is done in background and the client is not blocked waiting for its completion. Though the question then is - what to do if I want to get the response or outcome of the execution?

Async mode applies to operations that alter the state of the instance. This includes

  • start of new instance
  • update of variables (as it can trigger logic that listens to data changes e.g. conditional events)
  • completing of user tasks
  • canceling of user tasks
  • signals sent to workflow instance

There are at least two ways to approach it

  • Poll for outcomes
  • Request to post the outcomes to an URL
Polling for outcomes is certainly a valid option but only when we know that the instance is not finsihed. As you need to be aware of that the service backed by Automatiko will remove the instance once it's done. So in some situation it can be used but for sure not in all cases. To address this limitiation of polling approach, Automatiko can post back the outcomes as soon as it's done. This is based on a callback approach where the client calling the service in async mode can optionally set the callback url where to post the results. This is given in similar way as the async mode meaning via HTTP headers. The header that provides callback is called X-ATK-Callback and the value it expects is valid HTTP url.

Sample request (curl) that instructs the API to run in async mode with callback

  curl -X 'POST' \
    'http://localhost:8080/scripts' \
    -H 'accept: application/json' \
    -H 'Content-Type: application/json' \
    -H 'X-ATK-Mode: async' \
    -H 'X-ATK-Callback: https://my.callback.url' \
    -d '{
    "lastName": "doe",
    "name": "john"
  }'

As soon as processing of the request is completed the outcome (which is the complete data model of the workflow instance) will be posted to that URL. In addition to the payload that will be posted there is an extra header set that informs about the state of the workflow instance. The header that provides status information is called X-ATK-Status and will have on of the following values

  • Active
  • Completed
  • Aborted
  • Failed

Last but not least, callback might require authentication to be successfully invoked. Automatiko allows to configure globally authentication mechanism to be used when invoking async callbacks. Here are the supported authentications

  • none
  • basic
  • OAuth2
  • Custom HTTP header
  • on behalf - taking the header from the incoming call
  • query parameter on callback url e.g. api key
All the details on how to configure it will be described in the documentation once the release (0.6.0) is out.

At the end, have a look at a short screencast showing this feature in action.

Thanks for reading and make sure to drop us feedback or ask questions about this feature or others.

Photographs by Unsplash.