flow: PreserveOnRefresh - enabled, PushMode=Automatic, PushTransport=LongPolling - Application fails when page is reloaded
Description of the bug / feature
Due to certain environment conditions / restrictions, for one of our clients, WebSockets cannot be enabled, therefore, the application falls back to LONG_POLLING.
PreserveOnRefresh=enabled PushMode=AUTOMATIC PushTransport=LONG_POLLING
Everything works nice, with the following exception: if there is an Overlay opened (e.g. a ConfirmationDialog) and the user makes a page-reload (F5 or click from the browser), the application fails with the following exception and the result is an empty screen:
Assertion error: No child found with id 3
The following error is displayed on the server-side:
[Atmosphere-Shared-2] ERROR com.vaadin.flow.server.communication.PushAtmosphereHandler - Exception in push connection
org.eclipse.jetty.io.EofException
at org.eclipse.jetty.server.HttpConnection$SendCallback.reset(HttpConnection.java:708)
at org.eclipse.jetty.server.HttpConnection$SendCallback.access$300(HttpConnection.java:667)
at org.eclipse.jetty.server.HttpConnection.send(HttpConnection.java:526)
at org.eclipse.jetty.server.HttpChannel.sendResponse(HttpChannel.java:910)
at org.eclipse.jetty.server.HttpChannel.write(HttpChannel.java:987)
at org.eclipse.jetty.server.HttpOutput.channelWrite(HttpOutput.java:284)
at org.eclipse.jetty.server.HttpOutput.channelWrite(HttpOutput.java:268)
at org.eclipse.jetty.server.HttpOutput.flush(HttpOutput.java:713)
at org.eclipse.jetty.server.Response.flushBuffer(Response.java:1110)
at javax.servlet.ServletResponseWrapper.flushBuffer(ServletResponseWrapper.java:215)
at org.atmosphere.cpr.AtmosphereResponseImpl.flushBuffer(AtmosphereResponseImpl.java:506)
at org.atmosphere.cpr.AtmosphereInterceptorWriter.flush(AtmosphereInterceptorWriter.java:102)
at org.atmosphere.cpr.AtmosphereResponseImpl$Stream.flush(AtmosphereResponseImpl.java:1001)
at org.atmosphere.handler.AbstractReflectorAtmosphereHandler.onStateChange(AbstractReflectorAtmosphereHandler.java:156)
at com.vaadin.flow.server.communication.PushAtmosphereHandler.onStateChange(PushAtmosphereHandler.java:52)
at org.atmosphere.cpr.DefaultBroadcaster.invokeOnStateChange(DefaultBroadcaster.java:1037)
at org.atmosphere.cpr.DefaultBroadcaster.prepareInvokeOnStateChange(DefaultBroadcaster.java:1057)
at org.atmosphere.cpr.DefaultBroadcaster.executeAsyncWrite(DefaultBroadcaster.java:871)
at org.atmosphere.cpr.DefaultBroadcaster$2.run(DefaultBroadcaster.java:474)
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)
Minimal reproducible example
Code below and also as archive (it can be easily reproduced from a starter app). Steps to reproduce:
- Click on the “Say hello” button
- A Confirmation Dialog appears
- Reload the page (F5 or click from the browser)
package org.vaadin.example;
import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.button.ButtonVariant;
import com.vaadin.flow.component.confirmdialog.ConfirmDialog;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.component.page.Push;
import com.vaadin.flow.component.textfield.TextField;
import com.vaadin.flow.router.PreserveOnRefresh;
import com.vaadin.flow.router.Route;
import com.vaadin.flow.shared.communication.PushMode;
import com.vaadin.flow.shared.ui.Transport;
@Route("")
@PreserveOnRefresh
@Push(value = PushMode.AUTOMATIC, transport = Transport.LONG_POLLING)
public class MainView extends VerticalLayout {
public MainView() {
TextField textField = new TextField("Your name");
Button button = new Button("Say hello",
e -> {
ConfirmDialog cd = new ConfirmDialog();
cd.setText("Test content");
cd.open();
});
button.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
add(textField, button);
}
}
Expected behavior
No matter if WebSockets are enabled or disabled, the main layout should be rendered along with the Overlay, without exceptions.
Actual behavior
If WebSockets are enabled, and there is an Overlay opened, the issue cannot be reproduced, everything works as expected (main layout is rendered and the overlay is also rendered back). If WebSockets are enabled, and there is no Overlay opened, again, everything works as expected: main layout is rendered without issues. If WebSockets are disabled, and there is an Overlay opened, then a blank page is shown along with an exception:
Assertion error: No child found with id 3
If WebSockets are disabled, and there is no Overlay opened, then everything works as expected: main layout is rendered without issues.
The issue can also be reproduced, with any other component which is attached directly to the root.
Versions:
- Vaadin version: 14.4.7
- Java version: OpenJDK 1.8
- OS version: Linux / Windows / MacOS
- Browser version (if applicable): Chrome 88.0.4324.182 (Official Build) (x86_64), Safari 14.0.3 (16610.4.3.1.4) and Firefox
- Application Server (if applicable): Jetty 9.4.35.v20201120, Wildfly 18.0.1
- IDE (if applicable): -
Would be really appreciated if you can make some light here. Thank you.
About this issue
- Original URL
- State: closed
- Created 3 years ago
- Comments: 26 (16 by maintainers)
Commits related to this issue
- fix: use upgraded Atmosphere version for Push fixes #10103 — committed to vaadin/flow by deleted user 3 years ago
- fix: use upgraded Atmosphere version for Push fixes #10103 — committed to vaadin/flow by deleted user 3 years ago
- fix: use upgraded Atmosphere version for Push fixes #10103 — committed to vaadin/flow by deleted user 3 years ago
- chore: ignore until flow issue #10103 is fixed — committed to vaadin/flow by taefi 3 years ago
- chore: add ignored test for long polling and @PreserveOnRefresh (#10317) * add IT to isolate the problem * ignore until flow issue #10103 is fixed — committed to vaadin/flow by taefi 3 years ago
- chore: add ignored test for long polling and @PreserveOnRefresh (#10317) * add IT to isolate the problem * ignore until flow issue #10103 is fixed — committed to vaadin/flow by taefi 3 years ago
- fix: Upgrade Atmosphere to 2.7.2 fixes #10103 — committed to vaadin/flow by Artur- 3 years ago
- fix: Upgrade to Atmosphere 2.7.2 and Atmosphere JS 3.1.2 fixes #10103 — committed to vaadin/flow by Artur- 3 years ago
- fix: Upgrade to Atmosphere 2.7.2 and Atmosphere JS 3.1.2 fixes #10103 — committed to vaadin/flow by Artur- 3 years ago
- fix: Upgrade to Atmosphere 2.7.2 and Atmosphere JS 3.1.2 (#11935) fix: Upgrade to Atmosphere 2.7.2 and Atmosphere JS 3.1.2 fixes #10103 — committed to vaadin/flow by Artur- 3 years ago
- fix: Upgrade to Atmosphere 2.7.2 and Atmosphere JS 3.1.2 (#11935) fix: Upgrade to Atmosphere 2.7.2 and Atmosphere JS 3.1.2 fixes #10103 — committed to vaadin/flow by Artur- 3 years ago
- fix: Upgrade to Atmosphere 2.7.3 and Atmopshere JS 3.1.3 Fixes #10103 — committed to vaadin/flow by Artur- 2 years ago
- fix: Upgrade to Atmosphere 2.7.3 and Atmopshere JS 3.1.3 Fixes #10103 — committed to vaadin/flow by Artur- 3 years ago
- fix: Upgrade to Atmosphere 2.7.3 and Atmopshere JS 3.1.3 Fixes #10103 — committed to vaadin/flow by Artur- 3 years ago
- fix: Upgrade to Atmosphere 2.7.3 and Atmopshere JS 3.1.3 Fixes #10103 — committed to vaadin/flow by Artur- 3 years ago
- fix: Upgrade to Atmosphere 2.7.3 and Atmopshere JS 3.1.3 Fixes #10103 — committed to vaadin/flow by Artur- 3 years ago
- fix: Upgrade to Atmosphere 2.7.3 and Atmopshere JS 3.1.3 (#12738) Fixes #10103 — committed to vaadin/flow by Artur- 2 years ago
So this is an Atmosphere issue and it’s fixed in
2.7.0and3.1.0. https://github.com/Atmosphere/atmosphere/commit/8f082dafb526ee08c0cb534c2c825d052e6e9b24 https://github.com/Atmosphere/atmosphere-javascript/commit/a1cf7a11b9043707d840c91e27968b06f8a71998We have to update JS version AND Java Atmosphere binaries since change affects the server side code as well.
OK, this is pure Push issue related to the fact that Push connection has not been closed properly most likely.
If I comment out closing Push connection in the
vaadinPush.jsthen the error in the console is not shown. But the bug is still there.The problem appeared with https://www.chromestatus.com/feature/4664843055398912: it disallows calling
sendsynchronously on page close.There is a Chrome flag
#allow-sync-xhr-in-page-dismissalwhose value can be changed viachrome://flags/. If I set it totrue(and reload the browser) then I can’t reproduce the issue.So it proves that the issue is caused by the push connection behavior.
xhr closeshould be called somehow asynchronously invaadinPush.js.I don’t have any knowledge of Push. Help from someone who has this knowledge is needed.
@Artur- , could you please take a look ?
The problem is apparently caused by the fact that
ConfirmationDialoginstance is attached directly to theUIinstance.The workaround is extremely simple: don’t rely on auto attach the dialog to the
UI: attach the dialog instance to some nonUIcomponent. E.g. to theVerticalLayoutHi @silvan-lincan,
Great Info, thanks for the update. Yeah it is really strange.
I only followed your steps:
mvn clean installand thenmvn jetty:runTransport.LONG_POLLINGit is failing on my current version of chrome.about:configand set0fornetwork.websocket.max-connectionsand I can see the failingwsconnections, But, again everything works.Transport=WEBSOCKET_XHRresolves the issue on chrome also.So, I’m going to investigate more. First, I’ll update my Chrome to see what happens.
Hi @taefi,
MacOS (PushMode=Automatic, Transport=WEBSOCKET_XHR)
Linux (PushMode=Automatic, Transport=WEBSOCKET_XHR)
So, it is indeed odd that on your Chrome version on Mac you could reproduce this even with WebSockets enabled. Can it be related with the fact that you have 88.0.4324.150 and I have 88.0.4324.182? Even though, on Linux, I also have 88.0.4324.150, but cannot reproduce the issue when WebSockets are enabled.
Hi @taefi
Thank you very much for looking into this. Sorry for delay. I wanted to test again. MacOS (transport set to LONG_POLLING):
Linux (transport set to LONG_POLLING):
So, it seems indeed that on Firefox is working. Sorry about this, but I mentioned it as one of my colleagues saw this error also on Firefox, but I think this was some time ago.
Then the question is, do you really think this is only a browser (Chrome / Safari) related issue? The problem is, it seems that most of our users are using Chrome and Safari. Thank you.