protected void logoutAllSessions(boolean forceDisconnect) { log.info("Logging out all sessions"); if (sessions == null) { log.error("Attempt to logout all sessions before initialization is complete."); return; } for (Session session : sessions.values()) { try { session.logout(); } catch (Throwable e) { logError(session.getSessionID(), null, "Error during logout", e); } } if (forceDisconnect && isLoggedOn()) { for (Session session : sessions.values()) { try { if (session.isLoggedOn()) { session.disconnect("Forcibly disconnecting session", false); } } catch (Throwable e) { logError(session.getSessionID(), null, "Error during disconnect", e); } } } if (!forceDisconnect) { waitForLogout(); } }
protected void waitForLogout() { long start = System.currentTimeMillis(); Set<Session> loggedOnSessions; while (!(loggedOnSessions = getLoggedOnSessions()).isEmpty()) { try { Thread.sleep(100L); } catch (InterruptedException e) { log.error(e.getMessage(), e); } final long elapsed = System.currentTimeMillis() - start; Iterator<Session> sessionItr = loggedOnSessions.iterator(); while (sessionItr.hasNext()) { Session session = sessionItr.next(); if (elapsed >= session.getLogoutTimeout() * 1000L) { try { session.disconnect("Logout timeout, force disconnect", false); } catch (IOException e) { log.error(e.getMessage(), e); } sessionItr.remove(); } } // Be sure we don't look forever if (elapsed > 60000L) { log.warn("Stopping session logout wait after 1 minute"); break; } } }
@Override public boolean send(String data) { // Check for and disconnect slow consumers. if (maxScheduledWriteRequests > 0 && ioSession.getScheduledWriteMessages() >= maxScheduledWriteRequests) { Session qfjSession = (Session) ioSession.getAttribute(SessionConnector.QF_SESSION); try { qfjSession.disconnect("Slow consumer", true); } catch (IOException e) { } return false; } // The data is written asynchronously in a MINA thread WriteFuture future = ioSession.write(data); if (synchronousWrites) { try { if (!future.awaitUninterruptibly(synchronousWriteTimeout)) { log.error("Synchronous write timed out after " + synchronousWriteTimeout + "ms"); return false; } } catch (RuntimeException e) { log.error("Synchronous write failed: " + e.getMessage()); return false; } } return true; }
@Override public void exceptionCaught(IoSession ioSession, Throwable cause) throws Exception { boolean disconnectNeeded = false; Session quickFixSession = findQFSession(ioSession); Throwable realCause = cause; if (cause instanceof ProtocolDecoderException && cause.getCause() != null) { realCause = cause.getCause(); } else { Throwable chain = cause; while (chain != null && chain.getCause() != null) { chain = chain.getCause(); if (chain instanceof IOException) { realCause = chain; break; } } } String reason; if (realCause instanceof IOException) { if (quickFixSession != null && quickFixSession.isEnabled()) { reason = "Socket exception (" + ioSession.getRemoteAddress() + "): " + cause; } else { reason = "Socket (" + ioSession.getRemoteAddress() + "): " + cause; } disconnectNeeded = true; } else if (realCause instanceof CriticalProtocolCodecException) { reason = "Critical protocol codec error: " + cause; disconnectNeeded = true; } else if (realCause instanceof ProtocolCodecException) { reason = "Protocol handler exception: " + cause; } else { reason = cause.toString(); } if (disconnectNeeded) { try { if (quickFixSession != null) { quickFixSession.disconnect(reason, true); } else { log.error(reason, cause); ioSession.closeNow(); } } finally { ioSession.setAttribute("QFJ_RESET_IO_CONNECTOR", Boolean.TRUE); } } else { log.error(reason, cause); } }