diff options
author | Artur Signell <artur@vaadin.com> | 2013-03-22 17:45:26 +0200 |
---|---|---|
committer | Artur Signell <artur@vaadin.com> | 2013-04-02 10:40:33 +0300 |
commit | d4fcfdf7aa21899e8a621d48b8c1bb75fbd46c62 (patch) | |
tree | f39c4373b6977ad7322ce44dcc323f7f54e5534d /server | |
parent | 7dcccb01754a42338ec056cfda642bd8c28bb4d7 (diff) | |
download | vaadin-framework-d4fcfdf7aa21899e8a621d48b8c1bb75fbd46c62.tar.gz vaadin-framework-d4fcfdf7aa21899e8a621d48b8c1bb75fbd46c62.zip |
Ensure session is locked during cleanup (#10569)
* At the same time ensures request timer handling is done while session is locked (#10108)
Change-Id: Ifc36e1ac66d02e25fe98616319c014137bd94c10
Diffstat (limited to 'server')
-rw-r--r-- | server/src/com/vaadin/server/VaadinService.java | 39 | ||||
-rw-r--r-- | server/tests/src/com/vaadin/server/VaadinSessionTest.java | 57 |
2 files changed, 74 insertions, 22 deletions
diff --git a/server/src/com/vaadin/server/VaadinService.java b/server/src/com/vaadin/server/VaadinService.java index 20d87d6554..e4970d4104 100644 --- a/server/src/com/vaadin/server/VaadinService.java +++ b/server/src/com/vaadin/server/VaadinService.java @@ -1024,13 +1024,19 @@ public abstract class VaadinService implements Serializable { * * @param session */ - private void removeClosedUIs(VaadinSession session) { - for (UI ui : new ArrayList<UI>(session.getUIs())) { - if (ui.isClosing()) { - getLogger().log(Level.FINER, "Removing closed UI {0}", - ui.getUIId()); - session.removeUI(ui); - } + private void removeClosedUIs(final VaadinSession session) { + ArrayList<UI> uis = new ArrayList<UI>(session.getUIs()); + for (final UI ui : uis) { + ui.runSafely(new Runnable() { + @Override + public void run() { + if (ui.isClosing()) { + getLogger().log(Level.FINER, "Removing closed UI {0}", + ui.getUIId()); + session.removeUI(ui); + } + } + }); } } @@ -1177,10 +1183,23 @@ public abstract class VaadinService implements Serializable { public void requestEnd(VaadinRequest request, VaadinResponse response, VaadinSession session) { if (session != null) { - cleanupSession(session); - long duration = (System.nanoTime() - (Long) request + final VaadinSession finalSession = session; + + session.runSafely(new Runnable() { + @Override + public void run() { + cleanupSession(finalSession); + } + }); + + final long duration = (System.nanoTime() - (Long) request .getAttribute(REQUEST_START_TIME_ATTRIBUTE)) / 1000000; - session.setLastRequestDuration(duration); + session.runSafely(new Runnable() { + @Override + public void run() { + finalSession.setLastRequestDuration(duration); + } + }); } CurrentInstance.clearAll(); } diff --git a/server/tests/src/com/vaadin/server/VaadinSessionTest.java b/server/tests/src/com/vaadin/server/VaadinSessionTest.java index 6cad3307bf..e433e6fd05 100644 --- a/server/tests/src/com/vaadin/server/VaadinSessionTest.java +++ b/server/tests/src/com/vaadin/server/VaadinSessionTest.java @@ -25,30 +25,38 @@ import javax.servlet.http.HttpSessionBindingEvent; import junit.framework.Assert; import org.easymock.EasyMock; +import org.junit.Before; import org.junit.Test; import com.vaadin.server.ClientConnector.DetachEvent; import com.vaadin.server.ClientConnector.DetachListener; import com.vaadin.ui.UI; +import com.vaadin.util.CurrentInstance; public class VaadinSessionTest { - @Test - public void threadLocalsAfterUnderlyingSessionTimeout() { - - final VaadinServlet mockServlet = new VaadinServlet() { + private VaadinSession session; + private VaadinServlet mockServlet; + private VaadinServletService mockService; + private HttpSession mockHttpSession; + private WrappedSession mockWrappedSession; + private VaadinServletRequest vaadinRequest; + private UI ui; + + @Before + public void setup() { + mockServlet = new VaadinServlet() { @Override public String getServletName() { return "mockServlet"; }; }; - final VaadinServletService mockService = new VaadinServletService( - mockServlet, EasyMock.createMock(DeploymentConfiguration.class)); + mockService = new VaadinServletService(mockServlet, + EasyMock.createMock(DeploymentConfiguration.class)); - HttpSession mockHttpSession = EasyMock.createMock(HttpSession.class); - WrappedSession mockWrappedSession = new WrappedHttpSession( - mockHttpSession) { + mockHttpSession = EasyMock.createMock(HttpSession.class); + mockWrappedSession = new WrappedHttpSession(mockHttpSession) { final ReentrantLock lock = new ReentrantLock(); @Override @@ -60,10 +68,10 @@ public class VaadinSessionTest { } }; - final VaadinSession session = new VaadinSession(mockService); + session = new VaadinSession(mockService); session.storeInSession(mockService, mockWrappedSession); - final UI ui = new UI() { + ui = new UI() { Page page = new Page(this) { @Override public void init(VaadinRequest request) { @@ -79,7 +87,7 @@ public class VaadinSessionTest { return page; } }; - VaadinServletRequest vaadinRequest = new VaadinServletRequest( + vaadinRequest = new VaadinServletRequest( EasyMock.createMock(HttpServletRequest.class), mockService) { @Override public String getParameter(String name) { @@ -96,6 +104,11 @@ public class VaadinSessionTest { ui.setSession(session); session.addUI(ui); + } + + @Test + public void threadLocalsAfterUnderlyingSessionTimeout() { + final AtomicBoolean detachCalled = new AtomicBoolean(false); ui.addDetachListener(new DetachListener() { @Override @@ -112,4 +125,24 @@ public class VaadinSessionTest { session.valueUnbound(EasyMock.createMock(HttpSessionBindingEvent.class)); Assert.assertTrue(detachCalled.get()); } + + @Test + public void threadLocalsAfterSessionDestroy() { + final AtomicBoolean detachCalled = new AtomicBoolean(false); + ui.addDetachListener(new DetachListener() { + @Override + public void detach(DetachEvent event) { + detachCalled.set(true); + Assert.assertEquals(ui, UI.getCurrent()); + Assert.assertEquals(ui.getPage(), Page.getCurrent()); + Assert.assertEquals(session, VaadinSession.getCurrent()); + Assert.assertEquals(mockService, VaadinService.getCurrent()); + Assert.assertEquals(mockServlet, VaadinServlet.getCurrent()); + } + }); + CurrentInstance.clearAll(); + session.close(); + mockService.cleanupSession(session); + Assert.assertTrue(detachCalled.get()); + } } |