Browse Source

Defer session closing until the end of a request like with UIs (#10252)

Change-Id: I6231977a4d4f44cbee4a95664f0bef6acf4ca034
tags/7.0.0.beta10
Johannes Dahlström 11 years ago
parent
commit
e4206c2d2a

+ 28
- 15
server/src/com/vaadin/server/VaadinService.java View File

VaadinRequest request, Class<? extends UI> uiClass); VaadinRequest request, Class<? extends UI> uiClass);


/** /**
* Closes the VaadinServiceSession and discards all associated UI state.
* Sets the given session to be closed and all its UI state to be discarded
* at the end of the current request, or at the end of the next request if
* there is no ongoing one.
* <p>
* After the session has been discarded, any UIs that have been left open * After the session has been discarded, any UIs that have been left open
* will give an Out of sync error (
* {@link SystemMessages#getOutOfSyncCaption()}) error and a new session
* will be created for serving new UIs.
* will give a Session Expired error and a new session will be created for
* serving new UIs.
* <p> * <p>
* To avoid causing out of sync errors, you should typically redirect to * To avoid causing out of sync errors, you should typically redirect to
* some other page using {@link Page#setLocation(String)} to make the * some other page using {@link Page#setLocation(String)} to make the
* browser unload the invalidated UI. * browser unload the invalidated UI.
* *
* @see SystemMessages#getSessionExpiredCaption()
*
* @param session * @param session
* the session to close * the session to close
*/ */
public void closeSession(VaadinSession session) { public void closeSession(VaadinSession session) {
session.removeFromSession(this);
session.close();
} }


/** /**
closeInactiveUIs(session); closeInactiveUIs(session);
removeClosedUIs(session); removeClosedUIs(session);
} else { } else {
getLogger().fine(
"Closed inactive session " + session.getSession().getId());
closeSession(session);
if (!session.isClosing()) {
getLogger().fine(
"Closing inactive session "
+ session.getSession().getId());
closeSession(session);
}
session.removeFromSession(this);
} }
} }


/** /**
* Returns whether the given session is active or whether it can be closed. * Returns whether the given session is active or whether it can be closed.
* <p> * <p>
* A session is always active if
* {@link #getUidlRequestTimeout(VaadinSession) getUidlRequestTimeout} is
* negative. Otherwise, it is active if and only if the timeout has not
* expired.
* A session is active if and only if its {@link #isClosing} returns false
* and {@link #getUidlRequestTimeout(VaadinSession) getUidlRequestTimeout}
* is negative or has not yet expired.
* *
* @param session * @param session
* The session whose status to check * The session whose status to check
*
* @return true if the session is active, false if it could be closed. * @return true if the session is active, false if it could be closed.
*/ */
private boolean isSessionActive(VaadinSession session) { private boolean isSessionActive(VaadinSession session) {
long now = System.currentTimeMillis();
int timeout = 1000 * getUidlRequestTimeout(session);
return timeout < 0 || now - session.getLastRequestTimestamp() < timeout;
if (session.isClosing()) {
return false;
} else {
long now = System.currentTimeMillis();
int timeout = 1000 * getUidlRequestTimeout(session);
return timeout < 0
|| now - session.getLastRequestTimestamp() < timeout;
}
} }


private static final Logger getLogger() { private static final Logger getLogger() {

+ 21
- 10
server/src/com/vaadin/server/VaadinSession.java View File



private long lastRequestTimestamp = System.currentTimeMillis(); private long lastRequestTimestamp = System.currentTimeMillis();


private boolean closing = false;

private transient WrappedSession session; private transient WrappedSession session;


private final Map<String, Object> attributes = new HashMap<String, Object>(); private final Map<String, Object> attributes = new HashMap<String, Object>();
@Deprecated @Deprecated
public void removeFromSession(VaadinService service) { public void removeFromSession(VaadinService service) {
assert (getForSession(service, session) == this); assert (getForSession(service, session) == this);

session.setAttribute( session.setAttribute(
VaadinSession.class.getName() + "." + service.getServiceName(), VaadinSession.class.getName() + "." + service.getServiceName(),
null); null);
} }


/** /**
* Closes this session and discards all associated UI state. After the
* session has been discarded, any UIs that have been left open will give an
* Out of sync error ({@link SystemMessages#getOutOfSyncCaption()}) error
* and a new session will be created for serving new UIs.
* Sets this session to be closed and all UI state to be discarded at the
* end of the current request, or at the end of the next request if there is
* no ongoing one.
* <p>
* After the session has been discarded, any UIs that have been left open
* will give a Session Expired error and a new session will be created for
* serving new UIs.
* <p> * <p>
* To avoid causing out of sync errors, you should typically redirect to * To avoid causing out of sync errors, you should typically redirect to
* some other page using {@link Page#setLocation(String)} to make the * some other page using {@link Page#setLocation(String)} to make the
* browser unload the invalidated UI. * browser unload the invalidated UI.
* <p>
* This method is just a shorthand to
* {@link VaadinService#closeSession(VaadinSession)}
* *
* @see VaadinService#closeSession(VaadinSession)
* @see SystemMessages#getSessionExpiredCaption()
* *
*/ */
public void close() { public void close() {
getService().closeSession(this);
closing = true;
} }


/**
* Returns whether this session is marked to be closed.
*
* @see #close()
*
* @return
*/
public boolean isClosing() {
return closing;
}
} }

+ 1
- 1
uitest/src/com/vaadin/tests/applicationcontext/CloseSession.java View File



addComponent(log); addComponent(log);
addComponent(new Button( addComponent(new Button(
"Close VaadinServiceSession and redirect to Google",
"Close VaadinServiceSession and redirect elsewhere",
new Button.ClickListener() { new Button.ClickListener() {
@Override @Override
public void buttonClick(ClickEvent event) { public void buttonClick(ClickEvent event) {

Loading…
Cancel
Save