| Summary: | Tomcat hangs during shutdown | ||||||
|---|---|---|---|---|---|---|---|
| Product: | [RT] RAP | Reporter: | Daria Huber <daria.spam> | ||||
| Component: | RWT | Assignee: | Project Inbox <rap-inbox> | ||||
| Status: | RESOLVED FIXED | QA Contact: | |||||
| Severity: | major | ||||||
| Priority: | P2 | CC: | ivan, michi.fischer, rsternberg, vasko | ||||
| Version: | 1.5 | ||||||
| Target Milestone: | 2.2 RC1 | ||||||
| Hardware: | All | ||||||
| OS: | All | ||||||
| Whiteboard: | sr212 | ||||||
| Attachments: |
|
||||||
|
Description
Daria Huber
This was an issue with RAP 1.5 when UICallBack was active (blocked request was waiting) during the Tomcat shutdown. I thought that we have a bug opened about it, but I can't find it. I believe (can't reproduce it) that the issue is fixed in RAP 2.0. Please reopen if the issue persists in RAP 2.0+. (In reply to comment #1) > This was an issue with RAP 1.5 when UICallBack was active (blocked request > was waiting) during the Tomcat shutdown. I thought that we have a bug opened > about it, but I can't find it. I believe (can't reproduce it) that the issue > is fixed in RAP 2.0. Please reopen if the issue persists in RAP 2.0+. Thank's for your quick reply. Do you think it is possible to patch (or workaround) this bug in RAP 1.5? (In reply to comment #2) > (In reply to comment #1) > > This was an issue with RAP 1.5 when UICallBack was active (blocked request > > was waiting) during the Tomcat shutdown. I thought that we have a bug opened > > about it, but I can't find it. I believe (can't reproduce it) that the issue > > is fixed in RAP 2.0. Please reopen if the issue persists in RAP 2.0+. > > Thank's for your quick reply. > > Do you think it is possible to patch (or workaround) this bug in RAP 1.5? No... I don't think so. UICallBack was renamed (ServerPushSession) and redesigned in RAP 2.0. Together with all the API changes in RAP 2.0 it's not possible to extract a patch. Is it possible to kill my timer on shutdown? I tried with ServletContextListener and HttpSessionListener. I passed my timer object with HttpSessionEvent and tried to kill it on "contextDestroyed". But my application hangs already before the method "contextDestroyed" is executed. I have the same problem with ProgressMonitorDialog which blocks UIThread on a database query. During shutdown on a long running query I get a deadlock. I would like to kill my database thread on a shutdown. But it is the same problem as with the timer. "contextDestroyed" is executed too late. I tried with a database connection timeout, but my ProgressMonitorDialog still hangs. I can't just switch to RAP 2.X and have to find a solution for RAP 1.5. Have you any idea? I would be glad for any propose.... I will reopen this bug, because I've managed to reproduce a Tomcat hang on shutdown with our Workbench Demo and latest RAP 2.1 (master). In "Planning" perspective start a "Job with Dialog" and try to shutdown the Tomcat when the progress is running. Maybe this is related to bug 409843 or even it's a duplicate, but I will keep this bug open till we prove it. Using a distinct (final) lock object instead of 'this' in UIThread#getLock as suggested in bug 409843 does not fix the hang. More info from YourKit - after Tomcat shutdown two thread are still waiting: UIThread [183b969] [WAITING] CPU time: 3s java.lang.Object.wait() org.eclipse.rap.rwt.internal.lifecycle.UIThread.switchThread() org.eclipse.rap.rwt.internal.lifecycle.RWTLifeCycle.sleep() org.eclipse.swt.widgets.Display.sleep() org.eclipse.ui.application.WorkbenchAdvisor.eventLoopIdle(Display) org.eclipse.ui.internal.Workbench.runEventLoop(Window$IExceptionHandler, Display) org.eclipse.ui.internal.Workbench.runUI() org.eclipse.ui.internal.Workbench.access$5(Workbench) org.eclipse.ui.internal.Workbench$5.run() org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm, Runnable) org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Display, WorkbenchAdvisor) org.eclipse.ui.PlatformUI.createAndRunWorkbench(Display, WorkbenchAdvisor) org.eclipse.rap.demo.DemoWorkbench.createUI() org.eclipse.rap.rwt.internal.lifecycle.RWTLifeCycle.createUI() org.eclipse.rap.rwt.internal.lifecycle.RWTLifeCycle$UIThreadController.run() java.lang.Thread.run() org.eclipse.rap.rwt.internal.lifecycle.UIThread.run() Worker-JM [WAITING] CPU time: 0 java.lang.Object.wait(long) org.eclipse.core.internal.jobs.InternalWorker.run() It's absolutely the same hang with RAP 1.5 - this issue is not a regression. Created attachment 232539 [details] Thread Dump This is the thread dump attached to http://www.eclipse.org/forums/index.php/mv/msg/488636/1064034/#msg_1064034 In this thread dump the main Tomcat thread is blocked. This is not the case with my observation with Workbench Demo, where the Tomcat main thread is not blocked, but JavaVM is not destroyed. Daria, could you provide a simple project to reproduce the blocked Tomcat main thread? A started but "unused" ServerPushSession (aka. UICallBack) will also prevent Tomcat from a graceful shutdown. The stack trace below illustrates a situation where Registration.destroy() waits for the RWTServlet to finish processing the request. Since the request is blocked on the server, Tomcat shutdown will not finish. "localhost-startStop-2" - Thread t@90 java.lang.Thread.State: WAITING at java.lang.Object.wait(Native Method) - waiting on <8c5318> (a org.eclipse.equinox.http.servlet.internal.ServletRegistration) at java.lang.Object.wait(Object.java:503) at org.eclipse.equinox.http.servlet.internal.Registration.destroy(Registration.java:34) at org.eclipse.equinox.http.servlet.internal.ServletRegistration.destroy(ServletRegistration.java:37) at org.eclipse.equinox.http.servlet.internal.ProxyServlet.unregister(ProxyServlet.java:153) - locked <175f1c8> (a org.eclipse.equinox.http.servlet.HttpServiceServlet) at org.eclipse.equinox.http.servlet.internal.HttpServiceImpl.unregister(HttpServiceImpl.java:88) - locked <1ebb3fb> (a org.eclipse.equinox.http.servlet.internal.HttpServiceImpl) at org.eclipse.rap.rwt.osgi.internal.ApplicationReferenceImpl.unregisterServlet(ApplicationReferenceImpl.java:210) at org.eclipse.rap.rwt.osgi.internal.ApplicationReferenceImpl.unregisterServlets(ApplicationReferenceImpl.java:131) at org.eclipse.rap.rwt.osgi.internal.ApplicationReferenceImpl.stopRWTApplication(ApplicationReferenceImpl.java:119) at org.eclipse.rap.rwt.osgi.internal.ApplicationReferenceImpl.doStopApplication(ApplicationReferenceImpl.java:111) at org.eclipse.rap.rwt.osgi.internal.ApplicationReferenceImpl.stopApplication(ApplicationReferenceImpl.java:95) at org.eclipse.rap.ui.internal.servlet.HttpServiceTracker.removedService(HttpServiceTracker.java:52) at org.eclipse.rap.ui.internal.servlet.HttpServiceTracker.removedService(HttpServiceTracker.java:1) at org.osgi.util.tracker.ServiceTracker$Tracked.customizerRemoved(ServiceTracker.java:956) at org.osgi.util.tracker.ServiceTracker$Tracked.customizerRemoved(ServiceTracker.java:1) at org.osgi.util.tracker.AbstractTracked.untrack(AbstractTracked.java:341) at org.osgi.util.tracker.ServiceTracker.close(ServiceTracker.java:375) at org.eclipse.rap.ui.internal.servlet.HttpServiceTracker.close(HttpServiceTracker.java:64) at org.eclipse.ui.internal.WorkbenchPlugin.stop(WorkbenchPlugin.java:1332) ... Fixed as of commit 578019c1948fb46b09912b187b3c2bc46e5860a5. The problem was that the servlet bridge blocks the calling thread while unregistering servlets with standing requests. This lead to a lock state when trying to undeploy an application that has waiting push requests. To resolve the issue, servlets are now unregistered *after* the ApplicationContext is stopped. Stopping the application releases these push requests, so that unregistering does not block anymore. +1 for backporting to 2.1.2. If this fix has any unwanted side-effects, they would only affect the shutdown of an application, no regressions should be introduced at runtime. Backported to 2.1-maintenance branch with change https://git.eclipse.org/r/21232. |