* @since 7.0.0
*/
private void closeInactiveUIs(VaadinSession session) {
- String sessionId = session.getSession().getId();
- for (UI ui : session.getUIs()) {
+ final String sessionId = session.getSession().getId();
+ for (final UI ui : session.getUIs()) {
if (!isUIActive(ui) && !ui.isClosing()) {
- getLogger().log(Level.FINE,
- "Closing inactive UI #{0} in session {1}",
- new Object[] { ui.getUIId(), sessionId });
- ui.close();
+ ui.accessSynchronously(new Runnable() {
+ @Override
+ public void run() {
+ getLogger().log(Level.FINE,
+ "Closing inactive UI #{0} in session {1}",
+ new Object[] { ui.getUIId(), sessionId });
+ ui.close();
+ }
+ });
}
}
}
* the server that originates from this UI.
* {@link VaadinService#findUI(VaadinRequest)} uses this id to find the
* route to which the request belongs.
+ * <p>
+ * This method is not intended to be overridden. If it is overridden, care
+ * should be taken since this method might be called in situations where
+ * {@link UI#getCurrent()} does not return this UI.
*
- * @return
+ * @return the id of this UI
*/
public int getUIId() {
return uiId;
/**
* Returns the timestamp of the last received heartbeat for this UI.
+ * <p>
+ * This method is not intended to be overridden. If it is overridden, care
+ * should be taken since this method might be called in situations where
+ * {@link UI#getCurrent()} does not return this UI.
*
- * @see #heartbeat()
- * @see VaadinSession#cleanupInactiveUIs()
+ * @see VaadinService#closeInactiveUIs(VaadinSession)
*
* @return The time the last heartbeat request occurred, in milliseconds
* since the epoch.
* Sets the last heartbeat request timestamp for this UI. Called by the
* framework whenever the application receives a valid heartbeat request for
* this UI.
+ * <p>
+ * This method is not intended to be overridden. If it is overridden, care
+ * should be taken since this method might be called in situations where
+ * {@link UI#getCurrent()} does not return this UI.
*
* @param lastHeartbeat
* The time the last heartbeat request occurred, in milliseconds
if (getPushConnection() != null) {
// Push the Rpc to the client. The connection will be closed when
// the UI is detached and cleaned up.
+
+ // Can't use UI.push() directly since it checks for a valid session
+ if (session != null) {
+ session.getService().runPendingAccessTasks(session);
+ }
getPushConnection().push();
}
/**
* Returns whether this UI is marked as closed and is to be detached.
+ * <p>
+ * This method is not intended to be overridden. If it is overridden, care
+ * should be taken since this method might be called in situations where
+ * {@link UI#getCurrent()} does not return this UI.
*
* @see #close()
*
* Returns the internal push connection object used by this UI. This method
* should only be called by the framework. If the returned PushConnection is
* not null, it is guaranteed to have {@code isConnected() == true}.
+ * <p>
+ * This method is not intended to be overridden. If it is overridden, care
+ * should be taken since this method might be called in situations where
+ * {@link UI#getCurrent()} does not return this UI.
+ *
+ * @return the push connection used by this UI, <code>null</code> if there
+ * is no active push connection.
*/
public PushConnection getPushConnection() {
assert (pushConnection == null || pushConnection.isConnected());
* Sets the internal push connection object used by this UI. This method
* should only be called by the framework. If {@pushConnection} is not null,
* its {@code isConnected()} must be true.
+ *
+ * @param pushConnection
+ * the push connection to use for this UI
*/
public void setPushConnection(PushConnection pushConnection) {
// If pushMode is disabled then there should never be a pushConnection