// @NOTE keep flush private the preQ is not threadsafe private void flush(SessionWrapper sessW) { // disconnected drop any session messages // optionally keep any other messages or reject back upstream final Session session = sessW._session; final MessageQueue queue = sessW._queue; final MessageQueue preQ = sessW._preQueue; final MessageQueue syncQ = sessW._syncQueue; while (!syncQ.isEmpty()) { syncQ.next(); // DISCARD } Message head = null; Message tail = null; while (!queue.isEmpty()) { Message msg = queue.next(); if (msg.getReusableType() == CoreReusableType.NullMessage) break; if (session.discardOnDisconnect(msg) == false) { if (session.rejectMessageUpstream(msg, DISCONNECTED)) { // message recycled by successful reject processing } else { if (tail == null) { head = msg; tail = msg; } else { tail.attachQueue(msg); tail = msg; } } } else { _logMsg.copy(DROP_MSG).append(msg.getReusableType().toString()); _log.info(_logMsg); session.outboundRecycle(msg); } } // move remaining messages to the preQ if (head != null) { Message tmp = head; while (tmp != null) { Message next = tmp.getNextQueueEntry(); tmp.detachQueue(); preQ.add(tmp); tmp = next; } } }
@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); } }