// @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 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()); } } }
private void validateTicksize(Instrument instrument, double price) { TickType ts = instrument.getTickscale(); if (ts.canVerifyPrice()) { if (!ts.isValid(price)) { delim().append(INVALID_PRICE); ts.writeError(price, _err); } } else { ReusableString msg = TLC.instance().pop(); msg.append(MISSING_TICK).append(instrument.getRIC()); _log.warn(msg); TLC.instance().pushback(msg); } }
@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 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 }