package net.tomp2p.relay; import java.util.List; import java.util.Map; import java.util.TimerTask; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import net.tomp2p.connection.PeerConnection; import net.tomp2p.futures.BaseFutureAdapter; import net.tomp2p.futures.FutureBootstrap; import net.tomp2p.futures.FutureResponse; import net.tomp2p.p2p.builder.BootstrapBuilder; import net.tomp2p.peers.Number160; import net.tomp2p.peers.PeerAddress; import net.tomp2p.peers.PeerStatistic; /** * The PeerMapUpdateTask is responsible for periodically sending the unreachable * peer's PeerMap to its relays. This is important as the relay peers respond to * routing requests on behalf of the unreachable peers * */ public class PeerMapUpdateTask extends TimerTask { private static final Logger LOG = LoggerFactory.getLogger(PeerMapUpdateTask.class); private final RelayRPC relayRPC; private final BootstrapBuilder bootstrapBuilder; private final DistributedRelay distributedRelay; /** * Create a new peer map update task. * * @param relayRPC * the RelayRPC of this peer * @param bootstrapBuilder * bootstrap builder used to find neighbors of this peer * @param distributedRelay * set of the relay addresses * @param relayType */ public PeerMapUpdateTask(RelayRPC relayRPC, BootstrapBuilder bootstrapBuilder, DistributedRelay distributedRelay) { this.relayRPC = relayRPC; this.bootstrapBuilder = bootstrapBuilder; this.distributedRelay = distributedRelay; } @Override public void run() { // don't cancel, as we can be relayed again in future, only cancel if this peer shuts down. if (relayRPC.peer().isShutdown()) { this.cancel(); return; } // bootstrap to get updated peer map and then push it to the relay peers bootstrapBuilder.start().addListener(new BaseFutureAdapter<FutureBootstrap>() { @Override public void operationComplete(FutureBootstrap future) throws Exception { // send the peer map to the relays List<Map<Number160, PeerStatistic>> peerMapVerified = relayRPC.peer().peerBean().peerMap().peerMapVerified(); for (final Map.Entry<PeerAddress, PeerConnection> entry : distributedRelay.activeClients().entrySet()) { FutureResponse fr = relayRPC.sendPeerMap(entry.getKey(), entry.getValue(), peerMapVerified); //if we have buffered messages, send reply fr.addListener(new BaseFutureAdapter<FutureResponse>() { @Override public void operationComplete(FutureResponse future) throws Exception { if(future.isSuccess()) { relayRPC.handleBuffer(future.responseMessage()); } } }); LOG.debug("send peermap to {}", entry.getKey()); } } }); } }