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

Support live reload for SmallRye Reactive Messaging #15986

Merged
merged 1 commit into from Apr 5, 2021

Conversation

Ladicek
Copy link
Contributor

@Ladicek Ladicek commented Mar 24, 2021

Live reload check is performed with each incoming or outgoing
message, as processed by SmallRye Reactive Messaging connectors.

Resolves #3217

Live reload check is performed with each incoming or outgoing
message, as processed by SmallRye Reactive Messaging connectors.
@@ -228,7 +228,7 @@ public void afterEach(ExtensionContext extensionContext) throws Exception {
FileUtil.deleteDirectory(deploymentDir);
}
}
rootLogger.removeHandler(inMemoryLogHandler);
inMemoryLogHandler.clearRecords();
Copy link
Contributor Author

@Ladicek Ladicek Mar 24, 2021

Choose a reason for hiding this comment

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

Not exactly sure why we used to remove the in-memory log handler in afterEach, because that means capturing the log could only possibly have worked in the first test to be executed within one QuarkusDevModeTest instance. All the other remaining tests, should there be any, would see the captured log from the previous test, which seems obviously wrong.

Clearing the remembered content of the in-memory log handler, but leaving it attached to the root logger, seems like what should have been done since the beginning, but I'm not sure if there are any consequences I can't see.

Copy link
Member

Choose a reason for hiding this comment

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

Copy link
Contributor

@geoand geoand Mar 24, 2021

Choose a reason for hiding this comment

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

Yeah, the existing behavior seems wrong.... FWIW, QuarkusProdModeTest already does what @Ladicek did here

@Ladicek
Copy link
Contributor Author

Ladicek commented Mar 24, 2021

CI passed in my fork, and I don't see anything to be added here. Marking as ready.

@Ladicek Ladicek marked this pull request as ready for review March 24, 2021 14:46
Copy link
Member

@cescoffier cescoffier left a comment

Choose a reason for hiding this comment

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

Awesome! Thanks!

@cescoffier
Copy link
Member

Just a thought, with the http connector (Quarkus-http), how is it going to behave? Double reload? @michalszynkiewicz ?

@Ladicek
Copy link
Contributor Author

Ladicek commented Mar 25, 2021

Hmm good point, I didn't check that :-) But I guess that the live reload facility would ignore a 2nd request if 1st is still in progress? Well, I'd better look at it.

@michalszynkiewicz
Copy link
Member

I don't know either :) my guess would be that first reload would happen and then on the next "check for reload" would see no new changes, but that's just a guess

@cescoffier cescoffier merged commit 03df125 into quarkusio:main Apr 5, 2021
@quarkus-bot quarkus-bot bot added this to the 1.14 - main milestone Apr 5, 2021
@DevModeSupportConnectorFactory
@Priority(Interceptor.Priority.PLATFORM_BEFORE + 10)
public class DevModeSupportConnectorFactoryInterceptor {
private static Supplier<CompletableFuture<Boolean>> onMessage;
Copy link
Member

Choose a reason for hiding this comment

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

This should have been volatile

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ah that is true. I copied this pattern from other dev mode handlers, without too much thinking. I'll submit a PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done: #16263

@Override
public void onNext(Message<?> o) {
subscriber.onNext(o);
onMessage.get().join();
Copy link
Member

Choose a reason for hiding this comment

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

Won't this block the IO thread? Also won't the restart happen after the message has been delivered, rather than before, so the message is handled by the old code?

Copy link
Member

Choose a reason for hiding this comment

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

Hum, right - this method is going to be called on this I/O thread. Why is it require to join actually?

In theory, the connectors are passing the reactive streams TCK meaning that the onNext / onError / onComplete methods cannot be called concurrently (but could be called by different threads).

Also, we may want to reverse the onNext and onMessage call to handle the message with the new code.

Copy link
Contributor Author

@Ladicek Ladicek Apr 6, 2021

Choose a reason for hiding this comment

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

I actually did try something like onMessage.get().whenComplete((value, error) -> subscriber.onNext(o)), but that only works well with instrumentation-based reload. With full restart, you've got a new stream running, and no way to push the message there.

Note that this is @Outgoing -- so there's no user code handling the message (unless we had some kind of "message interceptors" per smallrye/smallrye-reactive-messaging#1141 :-) ). It's only the connector code at this point, submitting the message to a broker (or whatever is on the other side).

I trigger restart after submitting the message, so that the message isn't lost. Note that even if I triggered restart before submitting the message, it would still be processed by old code with full restart, because full restart takes a few seconds during which old code still runs. (At least that's what I observed.) And I wait for restart to finish so that no other message may come in and be lost. I realize blocking is a crude way to do it, but I figured that wouldn't be such a big deal in dev mode.

I'm open to other ideas of course.

I toyed with the idea of using the request protocol to handle this, but I really don't feel like I could do it correctly :-)

@Ladicek Ladicek deleted the reactive-messaging-live-reload branch April 6, 2021 06:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Trigger hot reload for reactive messaging
6 participants