Tracking in progress cadence workflow by client

1.1k views Asked by At

Let's say we need to generate the order after the user finalized his/her cart.

This is our steps to generate order:

  • generate an order in pending state (order microservice)
  • authorize user's credit(accounting microservice)
  • set status of the cart to closed(cart microservice)
  • approve the order (order microservice)

To do this we simply create a cadence workflow that calls to an activity for each step.

problem1: how the client can detect that the order creation is in progress for that cart if the user opens the cart again or refresh the page? (Note: assume our workflow is not executed by the worker yet)

My Solution for problem 1: create order and change its status to pending before running the workflow, so for the next requests, the client knows that the order is in pending status. but what happens if order creation was successful, but start workflow failed? it's not transactional (order creation and workflow run)

If this solution is your solution also and you accept its risk, tell me please. I'm new to cadence.

Problem 2: How to inform the client after the workflow has done and the order is ready?

Any solution or article or help, please?

1

There are 1 answers

4
Long Quanzheng On BEST ANSWER

Problem 1 : There are multiple solutions to consider:

1.1 Add a step in the workflow to change the order to pending state, before calling order microservice, instead of doing it outside of workflow. It will save you from the issue of consistency, you can add retry in the workflow to make sure the state are eventually consistent.

1.2 Add a query method to query the workflow state, and User/UI can make queryWorkflow call to retrieve the workflow state to see the order status.

1.3 Put the state into SearchAttribute of the workflow, and User/UI can make describeWorkflow call to get the state

1.4. After https://github.com/uber/cadence/issues/3729 is implemented, you can use memo instead of SearchAttribute like 1.3

Comparison: 1.1 is the choice if you think order storage is the source of truth of order state, 1.2~1.4 will make workflow become source of truth. It really depends on how you want to design the system architecture.

1.2 may not be a good choice if User/UI expects low latency. Because QueryCall may take a few seconds to return.

1.3~1.4 will be much more performant/fast. It only requires Cadence server make a DB call to get the workflow state.

1.3 has another benefit if you have Advanced visibility enabled with ElasticSearch+Kafka setup -- you can search/filter/count workflows by order states. But the limitation of 1.3 is that you should only put very small data like a string/integer, not a blob of state.

The benefit of 1.4 is that you could put a blob of state.

To prevent user finalizing a cart multiple times: When starting workflow, use a stable workflowID associated to the cart. So that you can call describeWF before allowing them to finalize/checkout a cart. The workflow is persisted once the StartWF req is accepted. If there is an active workflow(not failed/completed/timeouted), it means the cart is pending. For example if a cart uses a UUID, then you can use that UUID+prefix to make workflowID. Cadence guarantees workflowID uniqueness so there will be no race condition of starting two workflows for the same cart. If a checkout failed then a user can submit the checkout workflow again.

Problem 2 : It depends on what you want by "inform". The term inform sounds like asynchronous notification. If that's the case you can have another activity to send the notification to another microservice, or send a signal to another workflow that need the notification.

If here you means synchronous manner like showing on a WebUI, then it can be solved the same way as in the solutions I mentioned for problem 1.