Hi,
I am aware that we can start new workflow in async fashion using WorkflowClient.start() method. Do we have similar mechanism for query/signal method?
We have couple of reactive application which prefer these operations in non-blocking manner.
One way to achieve this is by wrapping query/signal call in CompletableFuture in client code.
Please suggest if there is any method in sdk that does this in better way?
We’ve dealt with a similar issue in our Kotlin code. In general, our code tries to use non-thread-blocking IO as much as possible. Unfortunately, there’s no such option when using a WorkflowClient or the stubs it generates - all the calls block on IO operations. To overcome that, we wrap all Temporal client calls with withContext(Dispatcher.IO) that tells Kotlin that the code can block a thread:
val workflowStub = workflowClient.newWorkflowStub<MyWorkflow>(workflowId)
withContext(Dispatchers.IO) {
workflowStub.signalMethod(signalArgument)
}
I believe a similar approach could be used by reactive applications by doing something like .subscribeOn(Schedulers.boundedElastic()) for Temporal client code that blocks on IO.
Right - maxim’s definition of “async” is a little different from how a reactive framework would define it. In a reactive framework, doing any blocking I/O at all on an event loop thread is not allowed, even if that blocking I/O should normally be “fast”, since there is always a chance a network issue makes it block for an extended period. As GreyTeardrop says, I think the only option right now is to offload those Temporal API calls to worker threads that can block.
I see. Please file an issue against Java SDK to get this added. I believe the gRPC library Temporal relies on supports nonblocking IO (through Netty). So such APIs should be possible, at least for starting, signaling, and querying workflows.