I’m attempting to use a background thread to keep a status panel up-to-date on my web application.
It needs to poll the database every second and update the panel.
I figured that the best way to do this would be to spawn a new thread and have it update the panel for me, which has not gone as smoothly as I would’ve liked. I have included the errors and code I’ve written below.
I’m using Vaadin 12.0.4. Any suggestions or ideas on how I can accomplish my goal are appreciated.
Here’s the related code:
- MainLayout.java
// @PWA(name = "DICES VoIP Web SAT", shortName = "WebSAT")
@HtmlImport("frontend://styles/shared-styles.html")
@Viewport("width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes")
@StyleSheet("frontend://styles/style.css")
@Push
public class MainLayout extends Div implements RouterLayout, PageConfigurator, BeforeEnterObserver {
...
}
- StatusPanel.java
public class StatusPanel extends HorizontalLayout {
Thread thread;
...
int i = 0;
@Override
protected void onAttach(AttachEvent attachEvent) {
// Start the data feed thread
thread = new FeederThread(attachEvent.getUI(), this);
thread.start();
}
@Override
protected void onDetach(DetachEvent detachEvent) {
// Cleanup
thread.interrupt();
thread = null;
}
private static class FeederThread extends Thread {
private final UI ui;
private final StatusPanel view;
private int count = 0;
public FeederThread(UI ui, StatusPanel view) {
this.ui = ui;
this.view = view;
}
@Override
public void run() {
try {
while(!Thread.currentThread().isInterrupted()) {
ui.access(() -> {
Result<SystemManagerDBO> systemManagerResult = Globals.dbi2.tables.systemManager.get("ip_address", ip_address);
if (systemManagerResult.getCount() >= 1) {
try {
SystemManagerDBO systemManager = systemManagerResult.getDBO();
RoleDBO role = systemManager.getHostDBO().getRoleDBO();
String serverText = systemManager.getHostDBO().getName() + view.i++;
view.serverLabel.setText(serverText);
System.out.println("Loading status bar: " + serverText + " " + view.serverLabel.getText());
setStatus(true, view.serverStatus);
if (role != null) {
view.roleLabel.setText(role.getName());
setStatus(true, view.roleStatus);
} else {
view.roleLabel.setText("N/A");
setStatus(false, view.roleStatus);
}
} catch (DBONotFoundException e) {
view.serverLabel.setText("Connected");
view.roleLabel.setText("N/A");
setStatus(true, view.serverStatus);
setStatus(false, view.roleStatus);
}
} else {
view.serverLabel.setText("Disconnected");
view.roleLabel.setText("N/A");
setStatus(false, view.serverStatus);
setStatus(false, view.roleStatus);
}
});
Thread.sleep(1000);
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return;
}
}
}
Output from my System.out.println() call that proves that this is getting ran every second as it should be, and that it’s updating the objects.
Loading status bar: WebSAT0 WebSAT0
Loading status bar: WebSAT1 WebSAT1
Loading status bar: WebSAT2 WebSAT2
Loading status bar: WebSAT3 WebSAT3
However, it’s not updating the HTML element, even though I have enabled @Push.
I have also tried manual push, same result.
I get the following errors when it’s running:
[Atmosphere-Shared-0]
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:714)
at org.eclipse.jetty.server.HttpConnection$SendCallback.access$300(HttpConnection.java:678)
at org.eclipse.jetty.server.HttpConnection.send(HttpConnection.java:536)
at org.eclipse.jetty.server.HttpChannel.sendResponse(HttpChannel.java:790)
at org.eclipse.jetty.server.HttpChannel.write(HttpChannel.java:846)
at org.eclipse.jetty.server.HttpOutput.write(HttpOutput.java:240)
at org.eclipse.jetty.server.HttpOutput.write(HttpOutput.java:216)
at org.eclipse.jetty.server.HttpOutput.flush(HttpOutput.java:398)
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)
[qtp353296011-18]
ERROR com.vaadin.flow.server.DefaultErrorHandler -
java.lang.UnsupportedOperationException: FIXME: Implement resync
at com.vaadin.flow.server.communication.ServerRpcHandler.handleRpc(ServerRpcHandler.java:315)
at com.vaadin.flow.server.communication.UidlRequestHandler.synchronizedHandleRequest(UidlRequestHandler.java:89)
at com.vaadin.flow.server.SynchronizedRequestHandler.handleRequest(SynchronizedRequestHandler.java:40)
at com.vaadin.flow.server.VaadinService.handleRequest(VaadinService.java:1533)
at com.vaadin.flow.server.VaadinServlet.service(VaadinServlet.java:227)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:865)
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:535)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:146)
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:548)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132)
at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:257)
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1595)
at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:255)
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1317)
at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:203)
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:473)
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1564)
at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:201)
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1219)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:144)
at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:219)
at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:126)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132)
at org.eclipse.jetty.server.Server.handle(Server.java:531)
at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:352)
at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:260)
at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:281)
at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:102)
at org.eclipse.jetty.io.ChannelEndPoint$2.run(ChannelEndPoint.java:118)
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.runTask(EatWhatYouKill.java:333)
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:310)
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.tryProduce(EatWhatYouKill.java:168)
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.run(EatWhatYouKill.java:126)
at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:366)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:762)
at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:680)
at java.lang.Thread.run(Thread.java:748)
And if the server is left running long enough I get the following errors aproximately every millisecond
[qtp353296011-26]
WARN com.vaadin.flow.server.communication.PushHandler - Invalid identifier in new connection received from 0:0:0:0:0:0:0:1
[qtp353296011-43]
WARN com.vaadin.flow.server.communication.PushHandler - Invalid identifier in new connection received from 0:0:0:0:0:0:0:1
[qtp353296011-26]
WARN com.vaadin.flow.server.communication.PushHandler - Invalid identifier in new connection received from 0:0:0:0:0:0:0:1
[qtp353296011-43]
WARN com.vaadin.flow.server.communication.PushHandler - Invalid identifier in new connection received from 0:0:0:0:0:0:0:1
[qtp353296011-26]
WARN com.vaadin.flow.server.communication.PushHandler - Invalid identifier in new connection received from 0:0:0:0:0:0:0:1
[qtp353296011-43]
WARN com.vaadin.flow.server.communication.PushHandler - Invalid identifier in new connection received from 0:0:0:0:0:0:0:1
[qtp353296011-26]
WARN com.vaadin.flow.server.communication.PushHandler - Invalid identifier in new connection received from 0:0:0:0:0:0:0:1
[qtp353296011-43]
WARN com.vaadin.flow.server.communication.PushHandler - Invalid identifier in new connection received from 0:0:0:0:0:0:0:1
[qtp353296011-26]
WARN com.vaadin.flow.server.communication.PushHandler - Invalid identifier in new connection received from 0:0:0:0:0:0:0:1