/** * Filter a message against the current sequencing state. If this method returns true, the message has been cleared * for sending and its sequencing information has been added to the state. If this method returns false, it has been * queued for later sending due to sequencing restrictions. This method also sets the sequence id as message * context. * * @param msg The message to filter. * @return True if the message was consumed. */ private boolean filter(Message msg) { long seqId = msg.getSequenceId(); msg.setContext(seqId); synchronized (this) { if (seqMap.containsKey(seqId)) { Queue<Message> queue = seqMap.get(seqId); if (queue == null) { queue = new LinkedList<Message>(); seqMap.put(seqId, queue); } if (msg.getTrace().shouldTrace(TraceLevel.COMPONENT)) { msg.getTrace().trace(TraceLevel.COMPONENT, "Sequencer queued message with sequence id '" + seqId + "'."); } queue.add(msg); return false; } seqMap.put(seqId, null); } return true; }
@Override public void processingDone(List<Processing> processings) { List<DocumentMessage> messages = new ArrayList<>(); if (messageFactory != null) { for (Processing processing : processings) { for (DocumentOperation documentOperation : processing.getDocumentOperations()) { messages.add(messageFactory.fromDocumentOperation(processing, documentOperation)); } } } if (log.isLoggable(LogLevel.DEBUG)) { log.log(LogLevel.DEBUG, "Forwarding " + messages.size() + " messages from " + processings.size() + " processings."); } if (messages.isEmpty()) { dispatchResponse(Response.Status.OK); return; } long inputSequenceId = requestMsg.getSequenceId(); ResponseMerger responseHandler = new ResponseMerger(requestMsg, messages.size(), this); for (Message message : messages) { // See comment for internalNoThrottledSource. dispatchRequest(message, (inputSequenceId == message.getSequenceId()) ? getUri().getPath() : "/" + internalNoThrottledSource, responseHandler); } }