/** * Add the given note to the trace information if tracing is enabled for the given level. * * @param level The trace level of the note. * @param note The note to add. * @return True if the note was added to the trace information, false otherwise. */ public boolean trace(int level, String note) { return trace(level, note, true); }
/** * <p>Adds a string to the trace of the message being routed.</p> * * @param level The level of the trace note. * @param note The note to add. */ public void trace(int level, String note) { node.getTrace().trace(level, note); }
public Message awaitMessage() { Message msg = null; try { msg = server.awaitMessage(60, TimeUnit.SECONDS); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } if (msg != null) { msg.getTrace().trace(0, "Message received by RemoteServer."); } return msg; }
/** * Invokes {@link RoutingNode#send()} on all routing nodes that are applicable for sending at the current time. */ public void resendScheduled() { if (queue.isEmpty()) return; List<RoutingNode> sendList = new LinkedList<RoutingNode>(); long now = SystemTimer.INSTANCE.milliTime(); while (!queue.isEmpty() && queue.peek().time <= now) { sendList.add(queue.poll().node); } for (RoutingNode node : sendList) { node.getTrace().trace(TraceLevel.COMPONENT, "Resender resending message."); node.send(); } }
/** * <p>Add an error to this reply. This method will also trace the error as long as there is any tracing * enabled.</p> * * @param error The error object to add. */ public void addError(Error error) { errors.add(error); getTrace().trace(TraceLevel.ERROR, error.toString()); }
public void sendReply(Reply reply) { reply.getTrace().trace(0, "Sending reply from RemoteServer."); server.sendReply(reply); }
private static Optional<ClusterState> clusterStateFromReply(final WrongDistributionReply reply) { try { return Optional.of(new ClusterState(reply.getSystemState())); } catch (Exception e) { reply.getTrace().trace(1, "Error when parsing system state string " + reply.getSystemState()); return Optional.empty(); } }
/** * 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; }
private void traceReplyFromRandomDistributor(WrongDistributionReply reply, ClusterState newState) { if (!reply.getTrace().shouldTrace(1)) { return; } if (cachedClusterState == null) { reply.getTrace().trace(1, "Message sent to * with no previous state, received version " + newState.getVersion()); } else if (newState.getVersion() == cachedClusterState.getVersion()) { reply.getTrace().trace(1, "Message sent to * found that cluster state version " + newState.getVersion() + " was correct."); } else if (newState.getVersion() > cachedClusterState.getVersion()) { reply.getTrace().trace(1, "Message sent to * updated cluster state to version " + newState.getVersion()); } else { reply.getTrace().trace(1, "Message sent to * retrieved older cluster state version " + newState.getVersion()); } }
/** * If a reply has been set containing an error, and {@link #shouldIgnoreResult()} returns <code>true</code>, this method * replaces that reply with one that has no error. * * @return Whether or not the reply was replaced. */ private boolean tryIgnoreResult() { if (!shouldIgnoreResult()) { return false; } if (reply == null || !reply.hasErrors()) { return false; } setReply(new EmptyReply()); trace.trace(TraceLevel.SPLIT_MERGE, "Ignoring errors in reply."); return true; }
public void handleErrorReply(Reply reply, Object untypedContext) { MessageContext messageContext = (MessageContext) untypedContext; if (messageContext.calculatedDistributor != null) { persistentFailureChecker.addFailure(messageContext.calculatedDistributor); if (reply.getTrace().shouldTrace(1)) { reply.getTrace().trace(1, "Failed with " + messageContext.toString()); } } } }
@Override public void handleReply(final Reply reply) { reply.getTrace().trace(6, "Reply received by MbusClient."); final ResponseHandler handler = (ResponseHandler)reply.getContext(); reply.popHandler(); // restore user context try { handler.handleResponse(new MbusResponse(StatusCodes.fromMbusReply(reply), reply)) .close(IgnoredCompletionHandler.INSTANCE); } catch (final Exception e) { log.log(LogLevel.WARNING, "Ignoring exception thrown by ResponseHandler.", e); } }
@Override public ContentChannel handleRequest(final Request request, final ResponseHandler handler) { if (!(request instanceof MbusRequest)) { throw new RequestDeniedException(request); } final Message msg = ((MbusRequest)request).getMessage(); msg.getTrace().trace(6, "Request received by MbusClient."); msg.pushHandler(null); // save user context final Long timeout = request.timeRemaining(TimeUnit.MILLISECONDS); if (timeout != null) { msg.setTimeReceivedNow(); msg.setTimeRemaining(Math.max(1, timeout)); // negative or zero timeout has semantics } msg.setContext(handler); msg.pushHandler(this); queue.add((MbusRequest)request); return null; }
@Override public void handleReply(Reply reply) { if (destroyed.get()) { reply.discard(); return; } boolean done; synchronized (lock) { --pendingCount; if (throttlePolicy != null) { throttlePolicy.processReply(reply); } done = (closed && pendingCount == 0); sendBlockedMessages(); } if (reply.getTrace().shouldTrace(TraceLevel.COMPONENT)) { reply.getTrace().trace(TraceLevel.COMPONENT, "Source session received reply. " + pendingCount + " message(s) now pending."); } ReplyHandler handler = reply.popHandler(); handler.handleReply(reply); if (done) { this.done.countDown(); } }
/** * Internal method for forwarding a sequenced message to the underlying sender. * * @param msg The message to forward. */ private void sequencedSend(Message msg) { if (msg.getTrace().shouldTrace(TraceLevel.COMPONENT)) { msg.getTrace().trace(TraceLevel.COMPONENT, "Sequencer sending message with sequence id '" + msg.getContext() + "'."); } msg.pushHandler(this); sender.handleMessage(msg); }
@Override public void handleMessage(Message msg) { if (!running.get()) { dispatchErrorReply(msg, ErrorCode.SESSION_BUSY, "Session temporarily closed."); return; } if (msg.getTrace().shouldTrace(6)) { msg.getTrace().trace(6, "Message received by MbusServer."); } Request request = null; ContentChannel content = null; try { request = new MbusRequest(container, uri, msg); content = request.connect(new ServerResponseHandler(msg)); } catch (RuntimeException e) { dispatchErrorReply(msg, ErrorCode.APP_FATAL_ERROR, e.toString()); } finally { if (request != null) { request.release(); } } if (content != null) { content.close(IgnoredCompletionHandler.INSTANCE); } }
/** * This method checks to see whether the string representation of the current hop is actually the name of another. * If a hop is found, the first hop of the current route is replaced by this. * * @return True if a hop was found and added. */ private boolean lookupHop() { RoutingTable table = mbus.getRoutingTable(msg.getProtocol()); if (table != null) { String name = route.getHop(0).getServiceName(); if (table.hasHop(name)) { HopBlueprint hop = table.getHop(name); configureFromBlueprint(hop); if (trace.shouldTrace(TraceLevel.SPLIT_MERGE)) { trace.trace(TraceLevel.SPLIT_MERGE, "Recognized '" + name + "' as " + hop + "."); } return true; } } return false; }
private Result sendInternal(Message message) { synchronized (lock) { if (closed) { return new Result(ErrorCode.SEND_QUEUE_CLOSED, "Source session is closed."); } if (throttlePolicy != null && ! throttlePolicy.canSend(message, pendingCount)) { return new Result(ErrorCode.SEND_QUEUE_FULL, "Too much pending data (" + pendingCount + " messages)."); } message.pushHandler(replyHandler); if (throttlePolicy != null) { throttlePolicy.processMessage(message); } ++pendingCount; } if (message.getTrace().shouldTrace(TraceLevel.COMPONENT)) { message.getTrace().trace(TraceLevel.COMPONENT, "Source session accepted a " + message.getApproxSize() + " byte message. " + pendingCount + " message(s) now pending."); } message.pushHandler(this); sequencer.handleMessage(message); return Result.ACCEPTED; }
@Override public final void send(RoutingNode recipient, Version version, byte[] payload, long timeRemaining) { SendContext ctx = new SendContext(recipient, timeRemaining); RPCServiceAddress address = (RPCServiceAddress)recipient.getServiceAddress(); Message msg = recipient.getMessage(); Route route = new Route(recipient.getRoute()); Hop hop = route.removeHop(0); Request req = encodeRequest(version, route, address,msg, timeRemaining, payload, ctx.trace.getLevel()); if (ctx.trace.shouldTrace(TraceLevel.SEND_RECEIVE)) { ctx.trace.trace(TraceLevel.SEND_RECEIVE, "Sending message (version " + version + ") from " + clientIdent + " to '" + address.getServiceName() + "' with " + ctx.timeout + " seconds timeout."); } if (hop.getIgnoreResult()) { address.getTarget().getJRTTarget().invokeVoid(req); if (ctx.trace.shouldTrace(TraceLevel.SEND_RECEIVE)) { ctx.trace.trace(TraceLevel.SEND_RECEIVE, "Not waiting for a reply from '" + address.getServiceName() + "'."); } Reply reply = new EmptyReply(); reply.getTrace().swap(ctx.trace); net.getOwner().deliverReply(reply, recipient); } else { req.setContext(ctx); address.getTarget().getJRTTarget().invokeAsync(req, ctx.timeout, this); } req.discardParameters(); // allow garbage collection of request parameters }
@Override public final void handleReply(Reply reply) { ReplyContext ctx = (ReplyContext)reply.getContext(); reply.setContext(null); // Add trace information. if (reply.getTrace().shouldTrace(TraceLevel.SEND_RECEIVE)) { reply.getTrace().trace(TraceLevel.SEND_RECEIVE, "Sending reply (version " + ctx.version + ") from " + serverIdent + "."); } // Encode and return the reply through the RPC request. byte[] payload = new byte[0]; if (reply.getType() != 0) { Protocol protocol = net.getOwner().getProtocol(reply.getProtocol()); if (protocol != null) { payload = protocol.encode(ctx.version, reply); } if (payload == null || payload.length == 0) { reply.addError(new Error(ErrorCode.ENCODE_ERROR, "An error occured while encoding the reply.")); } } createResponse(ctx.request.returnValues(), reply, ctx.version, payload); ctx.request.returnRequest(); }