A hypothetical synchronous operation, a REQUEST->RESPONSE call using a message bus is not 'that' difficult.
Publish the request to a specific topic with a specific request ID. Store this request in the service state. Subscribe to the response topic and filter until you get a payload with your response or you timeout.
Adding to that, for more fine grained control, the topic itself can contain the transaction id. So the topic is created per request, replied to by the 'server' with the response and then... something clean it up later.
It's not "difficult" to do, it's difficult to cover the multitude of concurrency issues that can occur and also difficult to make it fully fail-safe. Persistence of messages and the ability to replay in "passive" mode to recover state all start to surface.
My solution is not an example of how best to do this. My solution is an example of how to be lazy and avoid the bigger problems entirely.
Publish the request to a specific topic with a specific request ID. Store this request in the service state. Subscribe to the response topic and filter until you get a payload with your response or you timeout.
Adding to that, for more fine grained control, the topic itself can contain the transaction id. So the topic is created per request, replied to by the 'server' with the response and then... something clean it up later.
It's not "difficult" to do, it's difficult to cover the multitude of concurrency issues that can occur and also difficult to make it fully fail-safe. Persistence of messages and the ability to replay in "passive" mode to recover state all start to surface.
My solution is not an example of how best to do this. My solution is an example of how to be lazy and avoid the bigger problems entirely.