Introduce killing a zombie RWT UI session
authorMathieu Baudier <mbaudier@argeo.org>
Mon, 18 Dec 2023 07:47:12 +0000 (08:47 +0100)
committerMathieu Baudier <mbaudier@argeo.org>
Mon, 18 Dec 2023 07:47:12 +0000 (08:47 +0100)
org.argeo.api.cms/src/org/argeo/api/cms/ux/CmsUi.java
swt/org.argeo.cms.swt/src/org/argeo/cms/swt/CmsSwtUi.java
swt/rap/org.argeo.swt.specific.rap/src/org/argeo/eclipse/ui/specific/UiContext.java
swt/rcp/org.argeo.swt.specific.rcp/src/org/argeo/eclipse/ui/specific/UiContext.java

index ff6f5f081c4fbf985db0e85a4885353471301a00..fc8c9e0bc1405d3c74f14a3932383232e1771537 100644 (file)
@@ -8,8 +8,10 @@ public interface CmsUi {
 
        CmsView getCmsView();
 
-       long getLastAccess();
-
        void updateLastAccess();
 
+       default boolean isTimedOut() {
+               return false;
+       };
+
 }
index b16eb0f9e2b3a8912ed782efeb514c7f8abdea3f..d02ad3aec371202cb8f4c42364b15a45277b5605 100644 (file)
@@ -1,7 +1,5 @@
 package org.argeo.cms.swt;
 
-import java.util.TimerTask;
-
 import org.argeo.api.cms.ux.CmsUi;
 import org.argeo.api.cms.ux.CmsView;
 import org.eclipse.swt.layout.GridLayout;
@@ -14,7 +12,7 @@ public class CmsSwtUi extends Composite implements CmsUi {
 
        /** Last time the UI was accessed. */
        private long lastAccess = System.currentTimeMillis();
-       private TimerTask timeoutTask;
+//     private TimerTask timeoutTask;
        private long uiTimeout = 0;
 
        private CmsView cmsView;
@@ -30,44 +28,59 @@ public class CmsSwtUi extends Composite implements CmsUi {
                return cmsView;
        }
 
-       @Override
-       public long getLastAccess() {
-               return lastAccess;
-       }
-
        @Override
        public void updateLastAccess() {
                this.lastAccess = System.currentTimeMillis();
        }
 
        public void setUiTimeout(long uiTimeout) {
-               clearTimeoutTask();
+//             clearTimeoutTask();
                this.uiTimeout = uiTimeout;
                if (this.uiTimeout <= 0)
                        return;
-               final long timeoutTaskPeriod = 60 * 60 * 1000;// 1h
-               timeoutTask = cmsView.schedule(() -> {
-                       disposeIfTimedout();
-               }, timeoutTaskPeriod, timeoutTaskPeriod);
+               // TODO introduce mechanism to check whether the UI is "zombie"
+               // (that is the UI thread still exists, but cannot execute anything)
+//             final long timeoutTaskPeriod = 60 * 60 * 1000;// 1h
+//             timeoutTask = cmsView.schedule(() -> {
+//                     disposeIfTimedout();
+//             }, timeoutTaskPeriod, timeoutTaskPeriod);
+//             addDisposeListener((e) -> {
+//                     clearTimeoutTask();
+//             });
        }
 
-       /** Must be run in UI thread. */
-       public void disposeIfTimedout() {
-               if (isDisposed()) {
-                       clearTimeoutTask();
-                       return;
-               }
-               if (System.currentTimeMillis() - getLastAccess() >= uiTimeout) {
-                       dispose();
-                       clearTimeoutTask();
-               }
-       }
+//     /** Must be run in UI thread. */
+//     public void disposeIfTimedout() {
+//             System.out.println("Enter disposeIfTimedout");
+//             if (isDisposed()) {
+//                     clearTimeoutTask();
+//                     return;
+//             }
+//             if (isTimedOut()) {
+//                     dispose();
+//                     clearTimeoutTask();
+//                     System.out.println("Disposed after timeout");
+//             }
+//     }
+
+//     private void clearTimeoutTask() {
+//             if (timeoutTask != null) {
+//                     timeoutTask.cancel();
+//                     timeoutTask = null;
+//             }
+//     }
 
-       private void clearTimeoutTask() {
-               if (timeoutTask != null) {
-                       timeoutTask.cancel();
-                       timeoutTask = null;
-               }
+       @Override
+       public boolean isTimedOut() {
+               return uiTimeout > 0 && (System.currentTimeMillis() - lastAccess >= uiTimeout);
        }
 
+//     class DisposeIfTimedOutTask implements Runnable {
+//             public void run() {
+//                     disposeIfTimedout();
+//                     getDisplay().timerExec(1000, new DisposeIfTimedOutTask());
+//             }
+//
+//     }
+
 }
\ No newline at end of file
index a81d94d1190d4009912c413d2765f2b26bb54813..698fe2080486b3efbd119ccfd5f8021dfa75151b 100644 (file)
@@ -4,8 +4,10 @@ import java.util.Locale;
 
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSessionBindingListener;
 
 import org.eclipse.rap.rwt.RWT;
+import org.eclipse.rap.rwt.service.UISession;
 import org.eclipse.swt.widgets.Display;
 
 /** Singleton class providing single sources infos about the UI context. */
@@ -51,6 +53,11 @@ public class UiContext {
                display.setData(key, value);
        }
 
+       public static void killDisplay(Display display) {
+               UISession uiSession = RWT.getUISession(display);
+               ((HttpSessionBindingListener) uiSession).valueUnbound(null);
+       }
+
        private static Display getDisplay() {
                return Display.getCurrent();
        }
index 67b0e755cf1abda00a4447b5d996294018cdc3a5..a85d8914dd89bd04bd26ea4b50fcd9c9c207ac75 100644 (file)
@@ -44,6 +44,10 @@ public class UiContext {
                display.setData(key, value);
        }
 
+       public static void killDisplay(Display display) {
+               display.dispose();
+       }
+
        private static Display getDisplay() {
                return Display.getCurrent();
        }