Collect input from UI in the middle of workflow

Hi,

I have a scenario where I need to execute the following workflow:

  1. Run activity A (cannot modify its code due to internal limitations)
  2. Wait for user input via signal (this wait can potentially be very long)
  3. Run activity B (also immutable)

The UI needs to be notified when user input is required. I see two possible approaches:

  1. Implement an activity like request_user_data— This activity could trigger a notification (via database or external service) that user input is needed. However, I’m concerned that frequent calls of this activity may create overhead in terms of workflow history size and performance.
  2. Implement a query on the workflow — Then have an external worker periodically poll the workflow to check if user input is needed.

My questions:

  • What would be the most Temporal-native way to handle this scenario?
  • Can I rely on queries for building business logic in general? Because as I understand they don’t work if workflow is down (worker restart, etc).

Thanks.

It depends on how you expect to notify the user independently of the backend details. Is it an email, text message or something else?

Something like a push notification — when clicked, it opens a form requiring the details for the workflow to proceed.

Just for context: activities and the waiting period for user input can be long, as multiple people might be involved. For example, it could be part of an approval process: when multiple people need to provide some data and only after this workflow can proceed.

Then I would:

  • Send push notification from an activity
  • When clicked run a query against a workflow to determine the current page to show.
  • When the form is submitted send update to the workflow.

I recommend watching How Temporal Built its Self-Service Sign-up using Temporal Cloud talk that covers a similar use case.

1 Like

Thanks for sharing!

The updates are great, but in the example from recording, it looks like coordination happens via the UI — each step is just an update handler called one by one. In my case workflow executed in workflow method and drives the process: steps can request data and executes long.

Your approach (push from activity, identify step via query, then submit) works well for collecting data.

I have side question: how would you recommend tracking progress to show on the UI? Let’s forget about user input, I just have a pipeline of 50 business steps (individual activities or groups), and I just want to display kind of progress bar or step executing currently like 7/10.

I see a few options:

  1. Query (using query) current state, updated by the workflow, and poll periodically if UI opened.
  2. Report progress back to service (using activity) and then render UI based on this data (don’t use temporal for this).
  3. Use an update that waits for step execution: the UI queries the current step, sends an update to wait for it, updates the UI when finishes, and repeats. It sounds working, but I don’t want to bloat workflow execution history by 50 update calls for every step I have.

What’s preferred approach here?

BTW thanks for this post with update design patterns Announcing a new operation: Workflow Update | Temporal.

All three approaches are valid and used by different applications.

  1. Pro: the simplest. Cons: tradeoff between latency and frequency of queries.
  2. Pro: supports many UI sessions hitting the same workflow efficiently. Allows more complex queries, especially across multiple pipelines. Cons: eventually consistent, more complex to implement.
  3. Pro: The best for latency and doesn’t require frequent polls. Cons: Additional events in the history that grow over time.

In the future we plan to support a read only operation that blocks until a workflow reaches a specific state.

1 Like

With Update, try passing an update ID which will deduplicate the request.
Suppose you are waiting for state FOO, use that for your update ID. I think that will work without bloating your history.