-
Notifications
You must be signed in to change notification settings - Fork 15
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add waitForProcessingState to engine #218
Conversation
In some instances users might want to wait until the engine is processing. 1 such case is after increasing the time of the ActorScheduler. The engine should start triggering timers. It takes some time before the TRIGGERED records are written to the stream. By introducing a waitForProcessingState method users have the possibility to wait a given amount of time until the TRIGGERED record should be available.
a5cd3f2
to
e5a2797
Compare
In some instances users might want to wait until the engine is processing. 1 such case is after increasing the time of the ActorScheduler. The engine should start triggering timers. It takes some time before the TRIGGERED records are written to the stream. By introducing a waitForProcessingState method users have the possibility to wait a given amount of time until the TRIGGERED record should be available.
e5a2797
to
a6d916d
Compare
When we increase the time it takes some time before the engine has started processing again, and before it is writing new records to the stream. If we immediately wait for an idle state after increasting the time it will immediately say that it is idle, even though any potential timers have not yet been triggered. By waiting for up to 1 second to see if the engine has started processing again we can make sure the timers have been triggered. After this we still need to wait until the engine is idle again, to not modify the existing functionality.
a6d916d
to
8dfcf64
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good!
Some suggestions for name changes.
And maybe we should start writing tests also for classes like the idle state. The longer we wait, the more painful it will be to start writing tests for a class like that.
api/src/main/java/io/camunda/zeebe/process/test/api/InMemoryEngine.java
Outdated
Show resolved
Hide resolved
engine/src/main/java/io/camunda/zeebe/process/test/engine/IdleStateMonitor.java
Outdated
Show resolved
Hide resolved
qa/src/test/java/io/camunda/zeebe/process/test/qa/util/Utilities.java
Outdated
Show resolved
Hide resolved
waitForBusyState may be more descriptive to our users compared to waitForProcessingState.
To keep it in line with the waitForIdleState method a new `waitForBusyState()` has been introduced.
EngineStateMonitor is a more fitting name. This is because we're not only interested in the idle state of the engine, but also the busy state. Some methods have also been renamed to increase the clarity of what they do.
Similarly to waitForBusyState, waitForIdleState now has a timeout. If the engine has not reached an idle state within the specified timeout a TimeoutException will be thrown for the user to handle.
a29a95e
to
7e2f6d9
Compare
Thanks for reviewing @pihme. I've applied your suggestions and created a unit test for the |
waitForIdleState now requires a timeout to be specified. This commits adds this to all the tests that at some point wait for an idle state to be reached.
Add unit tests to verify the callbacks of the EngineStateMonitor are called at the correct times.
7e2f6d9
to
e69b281
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good!
I have some comments.
If you make bigger changes to the test, I would like to review those again. Otherwise, no need to do another review round
engine/src/main/java/io/camunda/zeebe/process/test/engine/EngineStateMonitor.java
Outdated
Show resolved
Hide resolved
engine/src/test/java/io/camunda/zeebe/process/test/engine/EngineStateMonitorTest.java
Outdated
Show resolved
Hide resolved
engine/src/test/java/io/camunda/zeebe/process/test/engine/EngineStateMonitorTest.java
Outdated
Show resolved
Hide resolved
engine/src/test/java/io/camunda/zeebe/process/test/engine/EngineStateMonitorTest.java
Show resolved
Hide resolved
@pihme I made some bigger changes to the test so I'd like another review. The biggest change is that I added a way to lock the state. This is required because when we switch to a busy state and register a callback the check if we are already in an idle state. This executes this method: private void forwardToLastEvent() {
synchronized (reader) {
while (reader.hasNext()) {
lastEventPosition = reader.next().getPosition();
}
}
} This iteration causes the state to become idle. Before this change as a workaround I registered the busy callback before actually changing the state to busy. This was confusing so I switched this up, but because of it I required a way to lock the state into a busy state. That's why I added the |
Renamed runProcessingCallbacks() to notifyProcessingCallbacks() Refactored the EngineStateMonitorTest - Extracted some shared functionality to a beforeEach method - Changed the structure of the tests to be more clear what it does. Given a callback, when the engine is busy/idle and we register a callback, then the callback should be notified. - Explicitly change the to an idle state in the idle state tests (even if we are already idle)
1c7b853
to
9c6c1c3
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Quick feedback; didn't do a full review yet
engine/src/test/java/io/camunda/zeebe/process/test/engine/EngineStateMonitorTest.java
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Definitely going in the right direction, Some details are still confusing
engine/src/test/java/io/camunda/zeebe/process/test/engine/EngineStateMonitorTest.java
Show resolved
Hide resolved
engine/src/test/java/io/camunda/zeebe/process/test/engine/EngineStateMonitorTest.java
Outdated
Show resolved
Hide resolved
Locking the state in idle/busy allows us to add the callback without it being triggered as a result from adding it. We can than make the part where it trigger more explicit by change to the other state.
…sync These positions should stay synchronized. Differences are going to cause weird behaviour where we think we are in an idle/busy state, but the positions indicate something else.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎉
Description
In #202 we have a flaky tests. In this test we have a process that's triggered by a timer start event. We increase the time of the engine to trigger this timer, sleep for 100 ms, wait for the engine to reach an idle state and assert that the process instance gets completed.
This solution has a few problems. First of all we use a
Thread.sleep()
to give the engine some time to trigger the timers. This is a dirty solution and it'd be better if we have a solution that only waits until the engine is running again.The second problem is that the engine has not always triggered the timers within 100 ms. Because of this the engine is considered idle, without actually finishing the processing.
This PR adds a
waitForProcessingState
to the engine. This method is very similar to thewaitForIdleState
method we already have. Just like that method it uses theIdleStateMonitor
with a callback to wait until the engine has started committing records again.A timeout needs to be specified to prevent waiting forever in case the engine will be permanently idle.
Related issues
closes #202
Definition of Done
Not all items need to be done depending on the issue and the pull request.
Code changes:
Testing:
Documentation: