From 61098bdf3cbca6ca040b97ce8b4eefe26302bd22 Mon Sep 17 00:00:00 2001 From: hengsin Date: Fri, 3 Apr 2020 20:06:07 +0800 Subject: [PATCH] IDEMPIERE-4206 Session timeout shown sometimes when changing roles Simplify Serverpush Code - remove retries and warning that just slow down things and doesn't really help. Change Role - With session invalidated and all components removed, there isn't need to destroy desktop. --- .../zk/atmosphere/AtmosphereServerPush.java | 30 +--------- .../zk/atmosphere/ZkAtmosphereHandler.java | 13 +++-- .../org/adempiere/webui/AdempiereWebUI.java | 56 +++---------------- .../src/org/adempiere/webui/apps/AEnv.java | 2 + .../webui/editor/WTableDirEditor.java | 16 ++++-- .../org/adempiere/webui/panel/RolePanel.java | 11 ---- .../webui/session/SessionContextListener.java | 2 +- .../ui/zk/websocket/WebSocketServerPush.java | 10 +--- 8 files changed, 31 insertions(+), 109 deletions(-) diff --git a/org.adempiere.ui.zk/WEB-INF/src/fi/jawsy/jawwa/zk/atmosphere/AtmosphereServerPush.java b/org.adempiere.ui.zk/WEB-INF/src/fi/jawsy/jawwa/zk/atmosphere/AtmosphereServerPush.java index d2cf3a125b..e9d79628d9 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/fi/jawsy/jawwa/zk/atmosphere/AtmosphereServerPush.java +++ b/org.adempiere.ui.zk/WEB-INF/src/fi/jawsy/jawwa/zk/atmosphere/AtmosphereServerPush.java @@ -24,7 +24,6 @@ import java.util.ArrayList; import java.util.List; import java.util.concurrent.atomic.AtomicReference; -import org.adempiere.webui.AdempiereWebUI; import org.atmosphere.cpr.AtmosphereResource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -63,7 +62,6 @@ public class AtmosphereServerPush implements ServerPush { private ExecutionCarryOver _carryOver; private final Object _mutex = new Object(); private List> schedules = new ArrayList<>(); - private long lastPiggyBack = 0; public AtmosphereServerPush() { String timeoutString = Library.getProperty("fi.jawsy.jawwa.zk.atmosphere.timeout"); @@ -164,7 +162,6 @@ public class AtmosphereServerPush implements ServerPush { @SuppressWarnings("unchecked") @Override public void onPiggyback() { - lastPiggyBack = System.currentTimeMillis(); Schedule[] pendings = null; synchronized (schedules) { if (!schedules.isEmpty()) { @@ -188,36 +185,11 @@ public class AtmosphereServerPush implements ServerPush { if (Executions.getCurrent() == null) { //schedule and execute in desktop's onPiggyBack listener scheduler.schedule(task, event); - boolean ok = false; try { - ok = commitResponse(); + commitResponse(); } catch (IOException e) { log.error(e.getMessage(), e); } - if (!ok) { - long l = lastPiggyBack; - for(int i = 0; i < 3 && !ok; i++) { - try { - Thread.sleep(100); - } catch (InterruptedException e1) {} - if (l == lastPiggyBack) { - try { - ok = commitResponse(); - } catch (IOException e) { - log.error(e.getMessage(), e); - } - } else { - ok = true; - } - } - if (!ok) { - Desktop d = desktop.get(); - log.warn("Failed to resume long polling resource" + (d != null ? " for desktop " + d.getId() : "")); - if (d != null) { - AdempiereWebUI.increaseScheduleFailures(d); - } - } - } } else { // in event listener thread, use echo to execute async synchronized (schedules) { diff --git a/org.adempiere.ui.zk/WEB-INF/src/fi/jawsy/jawwa/zk/atmosphere/ZkAtmosphereHandler.java b/org.adempiere.ui.zk/WEB-INF/src/fi/jawsy/jawwa/zk/atmosphere/ZkAtmosphereHandler.java index 4dd9f6a713..049aaf509c 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/fi/jawsy/jawwa/zk/atmosphere/ZkAtmosphereHandler.java +++ b/org.adempiere.ui.zk/WEB-INF/src/fi/jawsy/jawwa/zk/atmosphere/ZkAtmosphereHandler.java @@ -53,8 +53,10 @@ public class ZkAtmosphereHandler implements AtmosphereHandler { if (session.getWebApp() instanceof WebAppCtrl) { WebAppCtrl webAppCtrl = (WebAppCtrl) session.getWebApp(); Desktop desktop = webAppCtrl.getDesktopCache(session).getDesktopIfAny(dtid); - if (desktop == null) - log.warn("Could not find desktop: " + dtid); + if (desktop == null) { + if (log.isDebugEnabled()) + log.debug("Could not find desktop: " + dtid); + } return new Either("Could not find desktop", desktop); } return new Either("Webapp does not implement WebAppCtrl", null); @@ -124,9 +126,10 @@ public class ZkAtmosphereHandler implements AtmosphereHandler { Either serverPushEither = getServerPush(resource); String error = serverPushEither.getLeftValue(); if (error != null && serverPushEither.getRightValue() == null) { - log.warn("Bad Request. Error="+error+", Request="+resource.getRequest().getRequestURI()); - response.setStatus(HttpServletResponse.SC_BAD_REQUEST); - response.getWriter().write(error); + if (log.isDebugEnabled()) + log.warn("Bad Request. Error="+error+", Request="+resource.getRequest().getRequestURI()); + response.setStatus(HttpServletResponse.SC_NO_CONTENT); + response.getWriter().write(""); response.getWriter().flush(); return; } diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/AdempiereWebUI.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/AdempiereWebUI.java index a99ad6b54f..b64f92046c 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/AdempiereWebUI.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/AdempiereWebUI.java @@ -66,8 +66,6 @@ import org.zkoss.zk.ui.event.ClientInfoEvent; import org.zkoss.zk.ui.event.Event; import org.zkoss.zk.ui.event.EventListener; import org.zkoss.zk.ui.event.Events; -import org.zkoss.zk.ui.sys.DesktopCache; -import org.zkoss.zk.ui.sys.SessionCtrl; import org.zkoss.zk.ui.util.Clients; import org.zkoss.zul.Window; @@ -120,8 +118,6 @@ public class AdempiereWebUI extends Window implements EventListener, IWeb private ConcurrentMap m_URLParameters; - public static final String SERVERPUSH_SCHEDULE_FAILURES = "serverpush.schedule.failures"; - private static final String ON_LOGIN_COMPLETED = "onLoginCompleted"; public AdempiereWebUI() @@ -384,18 +380,16 @@ public class AdempiereWebUI extends Window implements EventListener, IWeb desktop.enableServerPush(false); Session session = logout0(); - DesktopCache desktopCache = ((SessionCtrl)session).getDesktopCache(); //clear context, invalidate session Env.getCtx().clear(); session.invalidate(); + desktop.setAttribute(DESKTOP_SESSION_INVALIDATED_ATTR, Boolean.TRUE); //redirect to login page - Executions.sendRedirect("index.zul"); - - if (desktopCache != null) - desktopCache.removeDesktop(Executions.getCurrent().getDesktop()); + Executions.sendRedirect("index.zul"); } + public void logoutAfterTabDestroyed(){ Desktop desktop = Executions.getCurrent().getDesktop(); if (desktop.isServerPushEnabled()) @@ -550,14 +544,14 @@ public class AdempiereWebUI extends Window implements EventListener, IWeb if (desktop.isServerPushEnabled()) desktop.enableServerPush(false); - Session session = logout0(); - DesktopCache desktopCache = ((SessionCtrl)session).getDesktopCache(); + logout0(); //clear context Env.getCtx().clear(); //invalidate session - ((SessionCtrl)session).invalidateNow(); + httpRequest.getSession(false).invalidate(); + desktop.setAttribute(DESKTOP_SESSION_INVALIDATED_ATTR, Boolean.TRUE); //put saved context into new session Map map = new HashMap(); @@ -568,14 +562,7 @@ public class AdempiereWebUI extends Window implements EventListener, IWeb newSession.setAttribute(SAVED_CONTEXT, map); properties.setProperty(SessionContextListener.SERVLET_SESSION_ID, newSession.getId()); - //redirect must happens before removeDesktop below, otherwise you get NPE - Executions.getCurrent().sendRedirect("index.zul"); - - //remove old desktop - if (desktopCache != null) { - desktop.setAttribute(DESKTOP_SESSION_INVALIDATED_ATTR, Boolean.TRUE); - desktopCache.removeDesktop(desktop); - } + Executions.getCurrent().sendRedirect("index.zul"); } @Override @@ -593,32 +580,5 @@ public class AdempiereWebUI extends Window implements EventListener, IWeb uploadSetting.append(",maxsize=").append(size); } return uploadSetting.toString(); - } - - /** - * Increase server push schedule failures count - * @param d - */ - public static void increaseScheduleFailures(Desktop d) { - Integer count = (Integer) d.getAttribute(SERVERPUSH_SCHEDULE_FAILURES); - if (count != null) - count = Integer.valueOf(count.intValue()+1); - else - count = Integer.valueOf(1); - d.setAttribute(SERVERPUSH_SCHEDULE_FAILURES, count); - } - - /** - * - * @param d - * @return server push schedule failures count - */ - public static int getScheduleFailures(Desktop d) { - int failures = 0; - Object attr = d.getAttribute(AdempiereWebUI.SERVERPUSH_SCHEDULE_FAILURES); - if (attr != null && attr instanceof Integer) - failures = ((Integer)attr).intValue(); - - return failures; - } + } } diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/AEnv.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/AEnv.java index 1dbfd1d449..d1d0693b41 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/AEnv.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/AEnv.java @@ -220,6 +220,8 @@ public final class AEnv MSession session = MSession.get(Env.getCtx(), false); // finish if (session != null) session.logout(); + + Env.setContext(Env.getCtx(), "#AD_Session_ID", (String)null); // } diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/editor/WTableDirEditor.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/editor/WTableDirEditor.java index 01bbf2c427..c355279dd6 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/editor/WTableDirEditor.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/editor/WTableDirEditor.java @@ -25,7 +25,6 @@ import java.util.Properties; import javax.swing.event.ListDataEvent; import javax.swing.event.ListDataListener; -import org.adempiere.webui.AdempiereWebUI; import org.adempiere.webui.ValuePreference; import org.adempiere.webui.apps.AEnv; import org.adempiere.webui.component.AutoComplete; @@ -66,6 +65,7 @@ import org.zkoss.zk.ui.event.Event; import org.zkoss.zk.ui.event.EventListener; import org.zkoss.zk.ui.event.Events; import org.zkoss.zk.ui.event.InputEvent; +import org.zkoss.zk.ui.sys.SessionCtrl; import org.zkoss.zk.ui.util.Clients; import org.zkoss.zk.ui.util.DesktopCleanup; import org.zkoss.zul.Comboitem; @@ -919,7 +919,15 @@ ContextMenuListener, IZoomableEditor private void refreshLookupList() { Desktop desktop = editor.getComponent().getDesktop(); - int failures = AdempiereWebUI.getScheduleFailures(desktop); + boolean alive = false; + if (desktop.isAlive() && desktop.getSession() != null) { + SessionCtrl ctrl = (SessionCtrl) desktop.getSession(); + alive = !ctrl.isInvalidated(); + } + if (!alive) { + ((ITableDirEditor)editor.getComponent()).cleanup(); + return; + } Executions.schedule(desktop, new EventListener() { @Override public void onEvent(Event event) { @@ -929,10 +937,6 @@ ContextMenuListener, IZoomableEditor } catch (Exception e) {} } }, new Event("onResetLookupList")); - int f = AdempiereWebUI.getScheduleFailures(desktop); - if (f > failures) { - ((ITableDirEditor)editor.getComponent()).cleanup(); - } } @Override diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/RolePanel.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/RolePanel.java index 8125b5e67e..1ea8f20ad0 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/RolePanel.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/RolePanel.java @@ -93,7 +93,6 @@ public class RolePanel extends Window implements EventListener, Deferrabl protected Combobox lstRole, lstClient, lstOrganisation, lstWarehouse; protected Label lblRole, lblClient, lblDef, lblOrganisation, lblWarehouse, lblDate; protected WDateEditor lstDate; - protected Button btnOk, btnCancel; /** Context */ protected Properties m_ctx; @@ -351,16 +350,6 @@ public class RolePanel extends Window implements EventListener, Deferrabl lstDate.setValue(new Timestamp(System.currentTimeMillis())); lstDate.getComponent().setId("loginDate"); - btnOk = new Button(); - btnOk.setId("btnOk"); - btnOk.setLabel("Ok"); - btnOk.addEventListener("onClick", this); - - btnCancel = new Button(); - btnCancel.setId("btnCancel"); - btnCancel.setLabel("Cancel"); - btnCancel.addEventListener("onClick", this); - // initial client - Elaine 2009/02/06 UserPreference userPreference = SessionManager.getSessionApplication().getUserPreference(); String initDefault = userPreference.getProperty(UserPreference.P_CLIENT); diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/session/SessionContextListener.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/session/SessionContextListener.java index c09c9933e0..a602339559 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/session/SessionContextListener.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/session/SessionContextListener.java @@ -325,7 +325,7 @@ public class SessionContextListener implements ExecutionInit, } } - public static void addDesktopId(int AD_Session_ID, String dtid) + public static synchronized void addDesktopId(int AD_Session_ID, String dtid) { String key = getSessionDesktopListKey(AD_Session_ID); @SuppressWarnings("unchecked") diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/idempiere/ui/zk/websocket/WebSocketServerPush.java b/org.adempiere.ui.zk/WEB-INF/src/org/idempiere/ui/zk/websocket/WebSocketServerPush.java index 0fb6822939..e0107e7542 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/idempiere/ui/zk/websocket/WebSocketServerPush.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/idempiere/ui/zk/websocket/WebSocketServerPush.java @@ -30,7 +30,6 @@ import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicReference; -import org.adempiere.webui.AdempiereWebUI; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.zkoss.zk.au.out.AuEcho; @@ -203,14 +202,7 @@ public class WebSocketServerPush implements ServerPush { if (Executions.getCurrent() == null) { //schedule and execute in desktop's onPiggyBack listener scheduler.schedule(task, event); - boolean ok = echo(); - if (!ok) { - Desktop d = desktop.get(); - log.warn("Failed to resume long polling resource" + (d != null ? " for desktop " + d.getId() : "")); - if (d != null) { - AdempiereWebUI.increaseScheduleFailures(d); - } - } + echo(); } else { // in event listener thread, use echo to execute async synchronized (schedules) {