Skip to content
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

feat(plc4j/spi): Add option to synchronously await response from PLC #1163

Merged
merged 1 commit into from
Oct 25, 2023

Conversation

takraj
Copy link
Contributor

@takraj takraj commented Oct 18, 2023

There might be cases when the driver needs to wait until the device responds our last request, before sending the next request. This feature attempts to make this more convenient.

@takraj takraj marked this pull request as draft October 18, 2023 20:49
There might be cases when the driver needs to wait until the device
responds our last request, before sending the next request. This
feature attempts to make this more convenient.
@takraj takraj marked this pull request as ready for review October 18, 2023 21:54
Copy link
Contributor

@chrisdutz chrisdutz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Checked it out and built with all modules and all tests ... no problems ;)

Copy link
Contributor

@splatch splatch left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've left some minor comments, I would appreciate message back on these, however even with these this PR looks good to go.

@@ -92,6 +93,8 @@ interface ContextHandler {

void cancel();

void awaitResponse() throws InterruptedException, ExecutionException;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@takraj I am asking myself if there is a point in making ContextHandler a separate thing, since it gets more and more similar to regular Future. I suppose you need awaitResponse in your future patches, wouldn't future or completable future fit better there?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yea, it's pretty much like a regular Future. The implementor DefaultContextHandler is basically only a proxy of another Future (i.e. HandlerRegistration), but seems to also trigger a callback, when cancelled. I'm not sure if we can get rid of that... But still, it could simply implement the normal Future<Void> interface instead of this one, and could be renamed to something like CancellationObserverFuture (?).

Did you think of something like this?

It would be even better if this Future could contain the response, and would completeExceptionally() in case of error/timeout. So instead of specifying a callback for these events, one could wait on the future, and then continue with processing the response.

@@ -152,6 +152,11 @@ protected void decode(ChannelHandlerContext channelHandlerContext, T t, List<Obj
continue;
}
// Timeout?
if (registration.isDone()) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is earlier condition which indicates that registration is cancelled. Maybe making a switch to isActive or similar would let us merge both? From Plc4xNettyWrapper perspective it doesn't matter if handler is cancelled or timed out, its relevant if its still needed to be looped over. With changes you did I think we got cancel and done callbacks within registration where appropriate log statements can be made.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I think you are right, these two could be merged together. Moreover, if isCancelled() is true, isDone() is also true, so it would be already enough to check the latter.

@@ -231,19 +236,21 @@ public Duration getTimeout() {
completionCallback.andThen(handler.getPacketConsumer()),
handler.getOnTimeoutConsumer(),
handler.getErrorConsumer(),
handler::confirmHandled,
handler::confirmError,
handler::cancel,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm trying to grasp with above three lines, cause I believe they are needed, but I would like to fully understand why they are added. Are we missing error callback on driver side? Anyhow, would be good if you could leave a comment in this place. If you spotted a bug then it would be great to have a test which will prevent us from getting regressions.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here, a new HandlerRegistration is created, copying the original, in order to inject a completionCallback before calling the packetConsumer. As confirmHandled() and cancel() are called for this new HandlerRegistration, the original one never became done, so ConversationContext.isDone() has never returned true.

I'll try to add test for this.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Its my bug then and test should belong to me! ;-)

onTimeoutConsumer.accept(e);
}
return timeoutException -> {
final HandlerRegistration registration = reference.get();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a note, syntax sugar makes stack traces harder to follow. Explicit creation of new Consumer was intentional to keep stacktrace more obvious.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, I wasn't aware of that. I'll change it back, and leave a comment.

@sruehl sruehl merged commit 6073d4b into apache:develop Oct 25, 2023
17 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants