/** * Schedules the given node for resending, if enabled. This will invoke {@link com.yahoo.messagebus.routing.RoutingNode#prepareForRetry()} * if the node was queued. This method is NOT thread-safe, and should only be called by the messenger thread. * * @param node The node to resend. * @return True if the node was queued. */ public boolean scheduleRetry(RoutingNode node) { Message msg = node.getMessage(); if (!msg.getRetryEnabled()) { return false; } int retry = msg.getRetry() + 1; double delay = node.getReply().getRetryDelay(); if (delay < 0) { delay = retryPolicy.getRetryDelay(retry); } if (msg.getTimeRemainingNow() * 0.001 - delay <= 0) { node.addError(ErrorCode.TIMEOUT, "Timeout exceeded by resender, giving up."); return false; } node.prepareForRetry(); // consumes the reply node.getTrace().trace(TraceLevel.COMPONENT, "Message scheduled for retry " + retry + " in " + delay + " seconds."); msg.setRetry(retry); queue.add(new Entry(node, SystemTimer.INSTANCE.milliTime() + (long)(delay * 1000))); return true; }
@Override public void run() { Message msg = decode(envelope.msg.getProtocol(), payload, Message.class); msg.getTrace().setLevel(envelope.msg.getTrace().getLevel()); msg.setRoute(envelope.msg.getRoute()).getRoute().removeHop(0); msg.setRetryEnabled(envelope.msg.getRetryEnabled()); msg.setRetry(envelope.msg.getRetry()); msg.setTimeRemaining(envelope.msg.getTimeRemainingNow()); msg.pushHandler(new ReplyHandler() { @Override public void handleReply(Reply reply) { new ReplyEnvelope(LocalNetwork.this, envelope, reply).send(); } }); owner.deliverMessage(msg, LocalServiceAddress.class.cast(envelope.recipient.getServiceAddress()) .getSessionName()); } });
@Override protected Request encodeRequest(Version version, Route route, RPCServiceAddress address, Message msg, long timeRemaining, byte[] payload, int traceLevel) { Request req = new Request(METHOD_NAME); Values v = req.parameters(); v.add(new StringValue(version.toString())); v.add(new StringValue(route.toString())); v.add(new StringValue(address.getSessionName())); v.add(new Int8Value(msg.getRetryEnabled() ? (byte)1 : (byte)0)); v.add(new Int32Value(msg.getRetry())); v.add(new Int64Value(timeRemaining)); v.add(new StringValue(msg.getProtocol())); v.add(new DataValue(payload)); v.add(new Int32Value(traceLevel)); return req; }
@Override protected Request encodeRequest(Version version, Route route, RPCServiceAddress address, Message msg, long timeRemaining, byte[] payload, int traceLevel) { Request req = new Request(METHOD_NAME); Values v = req.parameters(); v.add(new Int8Value(CompressionType.NONE.getCode())); v.add(new Int32Value(0)); v.add(new DataValue(new byte[0])); Slime slime = new Slime(); Cursor root = slime.setObject(); root.setString(VERSION_F, version.toString()); root.setString(ROUTE_F, route.toString()); root.setString(SESSION_F, address.getSessionName()); root.setString(PROTOCOL_F, msg.getProtocol().toString()); root.setBool(USERETRY_F, msg.getRetryEnabled()); root.setLong(RETRY_F, msg.getRetry()); root.setLong(TIMEREMAINING_F, msg.getTimeRemaining()); root.setLong(TRACELEVEL_F, traceLevel); root.setData(BLOB_F, payload); byte[] serializedSlime = BinaryFormat.encode(slime); Compressor.Compression compressionResult = compressor.compress(serializedSlime); v.add(new Int8Value(compressionResult.type().getCode())); v.add(new Int32Value(compressionResult.uncompressedSize())); v.add(new DataValue(compressionResult.data())); return req; }