@Override public void dispatchForSync(Message msg) { if (msg != null) { final MessageHandler handler = msg.getMessageHandler(); // cant be null NonBlockingSession session = (NonBlockingSession) handler; MessageQueue queue = session.getSendSyncQueue(); if (queue != null) { queue.add(msg); } else { // @TODO add ReusableString write( ReusableString buf ) to Message and log details // should NEVER happen _log.error(MISSING_HANDLER, ((Session) handler).getComponentId()); } } }
/** * @param session - a non blocking session ie an NIO one that wont block if socket cant read/write */ @Override public synchronized void addSession(final NonBlockingSession session) { SessionWrapper[] newSessions = new SessionWrapper[_sessions.length + 1]; int idx = 0; while (idx < _sessions.length) { newSessions[idx] = _sessions[idx]; ++idx; } newSessions[idx] = new SessionWrapper(session, session.getSendQueue(), session.getSendSyncQueue()); _sessions = newSessions; _fullyFlushed = false; }
@Override public void dispatch(final Message msg) { if (msg != null) { final MessageHandler handler = msg.getMessageHandler(); final NonBlockingSession session = (NonBlockingSession) handler; final MessageQueue queue = session.getSendQueue(); if (queue != null) { queue.add(msg); } else { // should NEVER happen ReusableString s = TLC.instance().pop(); s.copy(((Session) handler).getComponentId()) .append(": Missing Queue, unable to dispatch : "); msg.dump(s); _log.error(MISSING_HANDLER, s); TLC.instance().pushback(s); } } }
@Override public void handlerStatusChange(MessageHandler handler, boolean connected) { final int numSessions = _sessions.length; boolean allDisconnected = true; for (int i = 0; i < numSessions; i++) { SessionWrapper sessW = _sessions[i]; if (sessW._session == handler) { if (connected != sessW._connected) { final NonBlockingSession sess = sessW._session; _log.info( "MultiSession OutDispatcher " + getComponentId() + " : " + ((connected) ? "CONNECTED" : "DISCONNECTED") + " with " + sess.getComponentId() + ", canHandle=" + sess.canHandle() + ", isLoggedIn=" + sess.isLoggedIn()); sessW._connected = connected; } } if (sessW._connected) { allDisconnected = false; } } _fullyFlushed = false; synchronized (_disconnectLock) { // force mem barrier _allDisconnected = allDisconnected; } _ctl.statusChange(); }
@Override public void execute() throws Exception { _curSessW = _sessions[_nextSession]; final MessageQueue queue = _curSessW._queue; final MessageQueue preQueue = _curSessW._preQueue; final NonBlockingSession sess = _curSessW._session; if (++_nextSession >= _sessions.length) _nextSession = 0; if (_curSessW._connected && sess.canHandle()) { if (sess.isLoggedIn()) { if (sess.isMsgPendingWrite()) { sess.retryCompleteWrite(); } else if (preQueue.isEmpty()) { _curMsg = queue.poll(); // POLL = non blocking, causes MEM_READ barrier if (_curMsg != null && _curMsg.getReusableType() != CoreReusableType.NullMessage) { sess.handleNow(_curMsg); } } else { // QUEUED MESSAGES FROM PREVIOUS FLUSH CALLS _curMsg = preQueue.next(); if (_curMsg.getReusableType() != CoreReusableType.NullMessage) { sess.handleNow(_curMsg); } } } else { // SYNC mode final MessageQueue syncQueue = _curSessW._syncQueue; if (sess.isMsgPendingWrite()) { sess.retryCompleteWrite(); } else if (!syncQueue.isEmpty()) { _curMsg = syncQueue.next(); if (_curMsg.getReusableType() != CoreReusableType.NullMessage) { sess.handleNow(_curMsg); } } } } else { flush(_curSessW); } }
@Override public void handleExecutionException(Exception ex) { final NonBlockingSession sess = _curSessW._session; if (_curMsg != null && sess != null) { _log.warn( "SessionThreadedDispatcher " + getComponentId() + ", msgSeqNum=" + _curMsg.getMsgSeqNum() + ", sess=" + sess.getComponentId() + " exception " + ex.getMessage()); } flush(_curSessW); // some problem, possibly disconnect, poke controller to wake up anything waiting on controller // passive lock _ctl.statusChange(); // Mem barrier }