java.lang.IllegalStateException: Operation allowed only while eventLoop is running

Hi There.

I developing a workflow with a similar approach to this example:
https://github.com/temporalio/samples-java/blob/main/src/main/java/io/temporal/samples/hello/HelloSignal.java (GreetingWorkflowImpl)

The main differences are that I’m requesting the execution of a process to another microservice and this microservice will be sending signals to the workflow as it goes.

If a failure signal arrive, I have to request the execution up to 3 times.

When testing this workflow, I’m mocking the activity using mockito.
The mock for activityMock.retrieveExecutionTimeout() works fine,
but when the flow executes activityMock.retrieveCounter(anyInt()) it throws the exception described in the subject for this topic.

Any idea about why the activityMock works in the first call but throws and exception in the second call?

I’m providing you with much information as possible, but I have limitations to share the real stuff, sorry for that.

By the way, I’m using the java sdk plus temporal-testing version 1.6 as well as the temporal-testing-junit5 version 1.5.

see the code below:

@RegisterExtension
public static final TestWorkflowExtension testWorkflowExtension = TestWorkflowExtension.newBuilder()
.setWorkflowTypes(MyWorkflowImpl.class)
.setDoNotStart(true)
.build();

@Test
void createCustomDomain_FailedTest(TestWorkflowEnvironment testEnv, Worker worker, CustomDomainWorkflow workflow) {
MyActivity activityMock = Mockito.mock(CustomDomainActivity.class);
RequestDTO request = buildRequest();
SomeDTO response = buildDTOFromResultCode(SomeDTO.ResultCode.SUCCESS);

when(activityMock.createSomething(any(RequestDTO.class), anyString())).thenReturn(response);
when(activityMock.retrieveExecutionTimeout()).thenReturn(2L);

when(activityMock.retrieveCounter(anyInt())).thenReturn(2)
    .thenReturn(3);

//Execute
worker.registerActivitiesImplementations(activityMock);

testEnv.registerDelayedCallback(Duration.ofSeconds(4L), () -> {
    workflow.updateStatus(Constants.FAILURE);
});
testEnv.registerDelayedCallback(Duration.ofSeconds(4L), () -> {
    workflow.updateStatus(Constants.FAILURE);
});
testEnv.registerDelayedCallback(Duration.ofSeconds(4L), () -> {
    workflow.updateStatus(Constants.FAILURE);
});

testEnv.start();

String result = workflow.createStack(request, "ABC-123");
//Assertions after this.

}

1 Like

How is the workflow argument initialized?

There’s no workflow initialization, I’ve started following this example
https://github.com/temporalio/samples-java/blob/main/src/test/java/io/temporal/samples/hello/HelloActivityJUnit5Test.java

I’m assuming that is being initialized internally with default values.

If a failure signal arrive, I have to request the execution up to 3 times.

Execution of the workflow or activities? Asking because this error could happen if you are re-using activity stubs between workflow executions (for example when using dependency injection frameworks).
Having a small reproduce would help also I think.

1 Like

I’m confused.
On failure I need to retry the activity execution, but

The problem that I have is with the ActivityMock, meaning that I’m just creating the mock using mockito and later registering it with registerActivitiesImplementations for the test as shown through some examples from github as well as questions from the community.

For the real stuff I think I’m not recycling activity stubs, I always get activity stubs like this:

Workflow.newActivityStub(
clazz, ActivityOptions.newBuilder()
.setRetryOptions(
RetryOptions.newBuilder()
.setInitialInterval(Duration.ofMinutes(initialInterval))
.setMaximumAttempts(maximumAttempts)
.setBackoffCoefficient(1.0)
.build()
)
.setStartToCloseTimeout(Duration.ofMinutes(setStartToCloseTimeout))
.build());

I was getting Operation allowed only while eventLoop is running because of that. Thanks!