/**
*
*/
package net.varkhan.serv.p2p.message.transport;
import net.varkhan.base.management.report.JMXAverageMonitorReport;
import net.varkhan.serv.p2p.message.*;
import net.varkhan.serv.p2p.message.dispatch.MesgDispatcher;
import net.varkhan.serv.p2p.message.dispatch.MesgReceiver;
import net.varkhan.serv.p2p.message.dispatch.MesgSender;
import net.varkhan.serv.p2p.connect.PeerAddress;
import net.varkhan.serv.p2p.message.protocol.BinaryPayload;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
/**
* <b>.</b>
* <p/>
* @author varkhan
* @date Nov 19, 2009
* @time 12:53:57 AM
*/
@SuppressWarnings( { "UnusedDeclaration" })
public class LocalTransport implements MesgTransport, MesgSender {
public static final Logger log=LogManager.getLogger(LocalTransport.class);
private final MesgDispatcher dispatcher;
private final PeerAddress local;
private final String name;
private JMXAverageMonitorReport stats;
private volatile boolean run=false;
/**
* Creates a local PeerChannel.
*
*
* @param dispatcher the message dispatcher
* @param localPoint the local point node
* @param stats activity statistics collector
*/
public LocalTransport(MesgDispatcher dispatcher, PeerAddress localPoint,
JMXAverageMonitorReport stats) {
this.local=localPoint;
this.dispatcher=dispatcher;
this.stats=stats;
this.name="local"+"@"+localPoint.name();
}
/**********************************************************************************
** Lifecycle management
**/
@Override
public PeerAddress endpoint() {
return local;
}
/**
* Indicates whether the channel is started and able to handle messages
*
* @return {@code true} if the channel transport layer is ready to handle outgoing messages,
* and the listening thread is handling incoming messages
*/
public boolean isStarted() {
return run;
}
/**
* Start the channel.
*/
public void start() {
if(run) return;
if (log.isDebugEnabled()) {
log.debug(LocalTransport.class.getSimpleName()+": start "+name);
}
run = true;
}
/**
* Stop the channel.
*/
public void stop() {
run = false;
if (log.isDebugEnabled()) {
log.debug(LocalTransport.class.getSimpleName()+": stop "+name);
}
}
/**********************************************************************************
** Message transmission handling
**/
public boolean call(PeerAddress src, PeerAddress dst, String method, MesgPayload message, MesgReceiver handler) {
if(!run) {
stats.inc(LocalTransport.class.getSimpleName()+".Call.NotRunning");
return false;
}
// We only know how to send messages locally
if(!local.equals(src) || !local.equals(dst)) {
stats.inc(LocalTransport.class.getSimpleName()+".Call.NotLocal");
return false;
}
if(handler==null) {
dispatcher.call(src, dst, method, message, null, -1, null);
}
else {
long sequence = dispatcher.register(handler);
MesgPayload reply = new BinaryPayload();
dispatcher.call(src, dst, method, message, reply, sequence, this);
}
return true;
}
public boolean repl(PeerAddress src, PeerAddress dst, String method, MesgPayload message, long sequence) {
if(!run) {
stats.inc(LocalTransport.class.getSimpleName()+".Repl.NotRunning");
return false;
}
// We only know how to send messages locally
if(!local.equals(src) || !local.equals(dst)) {
stats.inc(LocalTransport.class.getSimpleName()+".Repl.NotLocal");
return false;
}
dispatcher.repl(src, dst, method, message, sequence);
return true;
}
public void send(PeerAddress src, PeerAddress dst, String method, MesgPayload message, long sequence) {
dispatcher.repl(dst, src, method, message, sequence);
}
}