I am facing an issue where @SignalMethod of my workflow is not getting executed.
Here is what my workflow looks like
@WorkflowInterface
public interface FeedWorkflow {
@WorkflowMethod
void execute(final WorkflowRequest request);
@SignalMethod
void processingComplete(final Summary summary);
}
public class FeedWorkflowImpl implements FeedWorkflow {
private Summary summary = null;
private final FeedWorkflowActivities activities;
public FeedWorkflowImpl() {
activities = Workflow.newActivityStub(FeedWorkflowActivities.class, <activityOptions>);
}
@Override
public Summary execute(@NonNull final WorkflowRequest request) {
try {
activities.startProcessing(request);
Workflow.await(() -> this.summary != null);
return summary;
} catch (final Throwable t) {
logger.error("Error executing workflow: ", t);
throw t;
}
}
@Override
public void processingComplete(@Nonnull final Summary summary) {
logger.info("Received completion signal with '{}'", summary);
this.summary = summary;
}
}
and this is how i am signalling the workflow from a different module (not part of the workflow)
final FeedWorkflow workflow =
workflowClient.newWorkflowStub(FeedWorkflow.class,
workflowId,
Optional.of(runId));
workflow.processingComplete(summary);
The signalling completes successfully and in the UI i can see that the workflow has been signalled (WorkflowExecutionSignaled). But dont see the log statement inside my signal method (processingComplete method) being executed and also because of this the workflow is stuck in the await block
Any idea what i am missing?
I am also seeing the following error in the logs which i think i related
io.temporal.internal.sync.DestroyWorkflowThreadError: null at io.temporal.internal.sync.WorkflowThreadContext.lambda$destroy$597e554$1(WorkflowThreadContext.java:260) ~[pservice-1.0.jar:?] at io.temporal.internal.sync.WorkflowThreadContext.mayBeEvaluate(WorkflowThreadContext.java:103) ~[pservice-1.0.jar:?] at io.temporal.internal.sync.WorkflowThreadContext.yield(WorkflowThreadContext.java:80) ~[pservice-1.0.jar:?] at io.temporal.internal.sync.WorkflowThreadImpl.yield(WorkflowThreadImpl.java:402) ~[pservice-1.0.jar:?] at io.temporal.internal.sync.WorkflowThread.await(WorkflowThread.java:45) ~[pservice-1.0.jar:?] at io.temporal.internal.sync.SyncWorkflowContext.await(SyncWorkflowContext.java:775) ~[pservice-1.0.jar:?]
@maxim Thanks, that explains why i am seeing the error log, however as you can see i am re-throwing the throwable so i m guessing that is not root cause of the issue.
Also to give you some context the reason i was logging throwable in my code was because previously i was incorrectly trying to get a workflow stub(outside a workflow) by doing: Workflow.newExternalWorkflowStub()
Since the above function when invoked outside a workflow throws an error instead of an exception, it took me a while to realize what the issue was. In order to get visibility into such errors while setting this up i decided to log them before re-throwing.
But the deserialization back to the object fails. I was able to get it fixed by setting @JsonAutoDetect correctly
Anyways what made this difficult to debug was that there were no exceptions messages in the logs. Is there any way i can tap these internal exception/error messages into log4j?
This is the log output I’m getting for unparsable signal:
08:25:47.652 [signal waitForName] ERROR i.t.i.sync.SyncWorkflowContext - Failure deserializing signal input for "waitForName" at eventId 5. Dropping it.
io.temporal.common.converter.DataConverterException: com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of `io.temporal.samples.hello.HelloSignal$SignalArg` (although at least one Creator exists): cannot deserialize from Object value (no delegate- or property-based Creator)
at [Source: (byte[])"{"name":"World"}"; line: 1, column: 2]
at io.temporal.common.converter.JacksonJsonPayloadConverter.fromData(JacksonJsonPayloadConverter.java:82)
at io.temporal.common.converter.DefaultDataConverter.fromPayload(DefaultDataConverter.java:105)
at io.temporal.common.converter.DataConverter.arrayFromPayloads(DataConverter.java:104)
at io.temporal.internal.sync.SyncWorkflowContext.lambda$registerSignal$3ac69c8f$1(SyncWorkflowContext.java:675)
at io.temporal.internal.sync.SyncWorkflowContext.signal(SyncWorkflowContext.java:639)
at io.temporal.internal.sync.WorkflowExecuteRunnable.processSignal(WorkflowExecuteRunnable.java:71)
at io.temporal.internal.sync.SyncWorkflow.lambda$handleSignal$2(SyncWorkflow.java:129)
at io.temporal.internal.sync.CancellationScopeImpl.run(CancellationScopeImpl.java:104)
at io.temporal.internal.sync.WorkflowThreadImpl$RunnableWrapper.run(WorkflowThreadImpl.java:107)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Caused by: com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of `io.temporal.samples.hello.HelloSignal$SignalArg` (although at least one Creator exists): cannot deserialize from Object value (no delegate- or property-based Creator)
at [Source: (byte[])"{"name":"World"}"; line: 1, column: 2]
at com.fasterxml.jackson.databind.exc.MismatchedInputException.from(MismatchedInputException.java:63)
at com.fasterxml.jackson.databind.DeserializationContext.reportInputMismatch(DeserializationContext.java:1455)
at com.fasterxml.jackson.databind.DeserializationContext.handleMissingInstantiator(DeserializationContext.java:1081)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromObjectUsingNonDefault(BeanDeserializerBase.java:1332)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:331)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:164)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4524)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3561)
at io.temporal.common.converter.JacksonJsonPayloadConverter.fromData(JacksonJsonPayloadConverter.java:80)
... 13 common frames omitted