
com.yahoo.messagebus.Routable Maven / Gradle / Ivy
// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.messagebus;
import com.yahoo.text.Utf8String;
/**
* Superclass for objects that can be either explicitly (Message) or implicitly (Reply) routed. Note that protocol
* implementors should never subclass this directly, but rather through the {@link Message} and {@link Reply} classes.
*
* A routable can be regarded as a protocol-defined value with additional message bus related state. The state is what
* differentiates two Routables that carry the same value. This includes the application context attached to the
* routable and the {@link CallStack} used to track the path of the routable within messagebus. When a routable is
* copied (if the protocol supports it) only the value part is copied. The state must be explicitly transfered by
* invoking the {@link #swapState(Routable)} method. That method is used to transfer the state from a message to the
* corresponding reply, or to a different message if the application decides to replace it.
*
* @author Simon Thoresen Hult
*/
public abstract class Routable {
private final CallStack callStack = new CallStack();
private final Trace trace = new Trace();
private Object context = null;
/**
* Discards this routable. Invoking this prevents the auto-generation of replies if you later discard the routable.
* This is a required step to ensure safe shutdown if you need destroy a message bus instance while there are still
* messages and replies alive in your application.
*/
public void discard() {
context = null;
callStack.clear();
trace.clear();
}
/**
* Swaps the state that makes this routable unique to another routable. The state is what identifies a routable for
* message bus, so only one message can ever have the same state. This function must be called explicitly when
* cloning and copying messages.
*
* @param rhs The routable to swap state with.
*/
public void swapState(Routable rhs) {
Object context = this.context;
this.context = rhs.context;
rhs.context = context;
callStack.swap(rhs.getCallStack());
trace.swap(rhs.getTrace());
}
/**
* Pushes the given reply handler onto the call stack of this routable, also storing the current context.
*
* @param handler The handler to push.
*/
public void pushHandler(ReplyHandler handler) {
callStack.push(handler, context);
}
/**
* This is a convenience method for calling {@link CallStack#pop(Routable)} on the {@link CallStack} of this
* Routable. It equals calling routable.getCallStack().pop(routable)
.
*
* @return The handler that was popped.
* @see CallStack#pop(Routable)
*/
public ReplyHandler popHandler() {
return callStack.pop(this);
}
/** Returns the context of this routable. */
public Object getContext() {
return context;
}
/**
* Sets a new context for this routable. Please note that the context is not something that is passed along a
* message, it is simply a user context for the handler currently manipulating a message. When the corresponding
* reply reaches the registered reply handler, its content will be the same as that of the outgoing message. More
* technically, this context is contained in the callstack of a routable.
*/
public void setContext(Object context) {
this.context = context;
}
/** Returns the callstack of this routable. */
public CallStack getCallStack() {
return callStack;
}
/** Returns the trace object of this routable. */
public Trace getTrace() {
return trace;
}
/**
* Return the name of the protocol that defines this routable. This must be implemented by all inheriting classes,
* and should then return the result of {@link com.yahoo.messagebus.Protocol#getName} of its protocol.
*
* @return the name of the protocol defining this message.
*/
public abstract Utf8String getProtocol();
/**
* Returns the type of this routable. The id '0' is reserved for the EmptyReply class. Other ids must be defined by
* the application protocol.
*/
public abstract int getType();
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy