Communication between Workflow and request handler

Hello. I am new to temporal and currently i’m working on creating a grpc request-handler in which I create a long workflow and trying to retrieve an information from there in order to respond to user’s grpc request whilst workflow execution continues. To be short, here is the usecase:

  1. User sends a GRPC request
  2. Send request to service A
  3. Get response from service A
  4. Some business logic
  5. Save information in Database
  6. Respond to user’s GRPC request
  7. Await an http callback from service A

I see the solution of this problem like following:

GRPC Handler Workflow
Accept GRPC request
ExecuteWorkflow()
QueryWorkflow(“getGRPCResponse”) in loop until retrieve a response ExecuteActivity(SendRequestToServiceA)
some business logic
ExecuteActivity(SaveToDatabase)
SetQueryHandler(“getGRPCResponse”, myResponse)
encoder.Get(&response) AwaitSignal() // waiting for callback
Respond to GRPC request ExecuteActivity(AnotherActivity1)
ExecuteActivity(AnotherActivity2)
ExecuteActivity(AnotherActivity3)
Finish execution

Are there more idiomatic approaches to do so?

Instead of polling using a query, you can use an Update to wait for the workflow to reach some state.

Thank you for your response. This is the way I do it now:

GRPC handler MyWorkflow
Accept Request
ExecuteWorkflow(MyWorkflow) ExecuteActivity(SendToServiceA)
handle = UpdateWorkflow(“myIntermediateResponse”) Some buiseness logic
handle.Get(&ret) ExecuteActivity(SaveInDB)
Respond with ret SetUpdateHandler(“myIntermediateResponse”, func() {return intermediateRet})
ExecuteActivity(OtherActivity1)
ExecuteActivity(OtherActivity2)
ExecuteActivity(OtherActivity3)

This way on step handle = UpdateWorkflow(“myIntermediateResponse”) i am getting into an error:
unknown update myIntermediateResponse. KnownUpdates=

, since at the moment of UpdateWorkflow request there was no handler matched to “myIntermediateResponse”. I guess I did not fully understand you.

The version of SDK Im currently using is go.temporal.io/sdk v1.27.0

The desired behaviour in this case is that handle = UpdateWorkflow(...) blocks until the update is handled by the workflow or the workflow fails.

You have to register the handler before it is called. So, register it at the beginning of the workflow function.

So how is this approach different from queries? Because I register the update handler at the beginning of the workflow, the UpdateWorkflow method returns the result immediately. The only way to achieve “blocking” behavior is to use a go channel to write response to, when the response is ready. But, if I’m right, this is considered as non-deterministic.

Queries cannot block and cannot mutate the workflow state.

Update handler can block and can mutate workflow state. You can achieve blocking semantic using Temporal equivalent of Go channel as well as Future or Await condition.

Thank you for your response!

1 Like