Handling promise timeout gracefully

hi,

We have childworkflows executing in parallel and we wait for all of them complete

Promise.allOf(promises).get();

Please suggest on how to handle gracefully if any of the childworkflows or promises times out.
Currently, our parent workflow is in failed state, also we want to further perform some process only the successful promises. we see the below stacktrace.

java.lang.Thread.getStackTrace(Thread.java:1564) io.temporal.internal.sync.CompletablePromiseImpl.throwFailure(CompletablePromiseImpl.java:136) io.temporal.internal.sync.CompletablePromiseImpl.getImpl(CompletablePromiseImpl.java:95) io.temporal.internal.sync.CompletablePromiseImpl.get(CompletablePromiseImpl.java:74) io.temporal.internal.sync.AllOfPromise.get(AllOfPromise.java:81) io.temporal.internal.sync.AllOfPromise.get(AllOfPromise.java:29) com.walmart.itemingestion.workflow.FeedProcessorCommon.process(FeedProcessorCommon.java:273) com.walmart.itemingestion.workflow.FeedProcessorCommon.process(FeedProcessorCommon.java:128) com.walmart.itemingestion.workflow.FeedIngestionV1WorkflowImpl.execute(FeedIngestionV1WorkflowImpl.java:36) sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) java.lang.reflect.Method.invoke(Method.java:498) io.temporal.internal.sync.POJOWorkflowImplementationFactory$POJOWorkflowImplementation$RootWorkflowInboundCallsInterceptor.execute(POJOWorkflowImplementationFactory.java:317) io.temporal.internal.sync.POJOWorkflowImplementationFactory$POJOWorkflowImplementation.execute(POJOWorkflowImplementationFactory.java:292) io.temporal.internal.sync.WorkflowExecuteRunnable.run(WorkflowExecuteRunnable.java:72) io.temporal.internal.sync.SyncWorkflow.lambda$start$0(SyncWorkflow.java:137) io.temporal.internal.sync.CancellationScopeImpl.run(CancellationScopeImpl.java:101) io.temporal.internal.sync.WorkflowThreadImpl$RunnableWrapper.run(WorkflowThreadImpl.java:111) java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) java.util.concurrent.FutureTask.run(FutureTask.java:266) java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) java.lang.Thread.run(Thread.java:750) Caused By: io.temporal.internal.statemachines.ChildWorkflowStateMachine.notifyTimedOut(ChildWorkflowStateMachine.java:264) io.temporal.internal.statemachines.FixedTransitionAction.apply(FixedTransitionAction.java:45) io.temporal.internal.statemachines.StateMachine.executeTransition(StateMachine.java:147) io.temporal.internal.statemachines.StateMachine.handleHistoryEvent(StateMachine.java:101) io.temporal.internal.statemachines.EntityStateMachineBase.handleEvent(EntityStateMachineBase.java:67) io.temporal.internal.statemachines.WorkflowStateMachines.handleSingleEvent(WorkflowStateMachines.java:235) io.temporal.internal.statemachines.WorkflowStateMachines.handleEventsBatch(WorkflowStateMachines.java:199) io.temporal.internal.statemachines.WorkflowStateMachines.handleEvent(WorkflowStateMachines.java:175) io.temporal.internal.replay.ReplayWorkflowRunTaskHandler.handleWorkflowTaskImpl(ReplayWorkflowRunTaskHandler.java:176) io.temporal.internal.replay.ReplayWorkflowRunTaskHandler.handleWorkflowTask(ReplayWorkflowRunTaskHandler.java:145) io.temporal.internal.replay.ReplayWorkflowTaskHandler.handleWorkflowTaskWithQuery(ReplayWorkflowTaskHandler.java:122) io.temporal.internal.replay.ReplayWorkflowTaskHandler.handleWorkflowTask(ReplayWorkflowTaskHandler.java:97) io.temporal.internal.worker.WorkflowWorker$TaskHandlerImpl.handle(WorkflowWorker.java:230) io.temporal.internal.worker.WorkflowWorker$TaskHandlerImpl.handle(WorkflowWorker.java:188) io.temporal.internal.worker.PollTaskExecutor.lambda$process$0(PollTaskExecutor.java:83) java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) java.lang.Thread.run(Thread.java:750)

java sdk: 1.7.0

try {
   Promise.allOf(promises).get();
} catch (...) {
 // Handle failure here
// You can use promise.isReady and promise.get
// to extract value or failure from promises
 ...
}

hi @maxim ,

thanks. It worked for timeout scenario. But not so well for “termination” (manually from UI) scenario.
In termination scenario, say 1 was terminated out of 5 promises, we need to wait for other 4 promises to complete.

Is this possible? maybe through handle or exceptionally ? Please guide me.

Termination by definition is like “kill -9”. It doesn’t give a workflow any chance to perform the cleanup. Use cancellation or signals to give a workflow a chance to perform the cleanup.

1 Like