I am trying to create a workflow that can be described as follows:
- Download some file in the local filesystem.
- Upload the local file to some other system in order to process it.
- Wait for a callback to signal the processing is done with the results, not dependent on any host.
- Save the results and trigger some more operations.
I am implementing it using a “local” queue, using the “host dependent queue” pattern from the FileProcessingWorkflow example to make the steps 1 and 2 run on the same host.
In order to wait for the completion signal, I am using the following pattern:
while (true) {
Workflow.sleep(LOOP_TIMEOUT);
if (!Objects.isNull(result)) {
log.info("result received!");
break;
} else {
log.info("Still waiting...");
}
}
where the signal method just assigns the result
field of the workflow class.
I am not sure at all the approach is sound, especially in regards to the sleep loop. I am wondering if it would make more sense in regards to temporal best practices to split my workflow in two, one to download and submit the file for processing and once I get my callback, to trigger a second workflow with the processing result as input.
Second question, more for my understanding of temporal: I started by implementing the wait section described above as:
while (true) {
if (!Workflow.await(LOOP_TIMEOUT, () -> !Objects.isNull(result))) {
break;
}
}
But then my test was failing with a “possible deadlock detected: workflow thread did not yield control within 1s”. Why is that ?
I was sending the signal using a mock of my activity using the following code:
willAnswer((Answer<Void>) invocation -> {
testEnv.registerDelayedCallback(Duration.ofSeconds(2), () -> {
workflowById.completeProcessing(result);
});
return null;
}).given(hostSpecificActivity).submitForProcessing(any(), any());
Could you explain why changing from await()
to sleep()
made it work ? If temporal expects the workflow thread to not block, what is its purpose ?