package com.limegroup.gnutella;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import org.limewire.core.settings.PingPongSettings;
import org.limewire.inject.EagerSingleton;
import org.limewire.lifecycle.Service;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.name.Named;
import com.limegroup.gnutella.messages.PingRequest;
import com.limegroup.gnutella.messages.PingRequestFactory;
/**
* This class continually sends broadcast pings on behalf of an Ultrapeer
* to update the host caches of both itself and its leaves. This class
* reduces overall ping and pong traffic because it allows us not to forward
* pings received from other hosts. Instead, we use pong caching to respond
* to those pings with cached pongs, and send pings periodically in this
* class to obtain fresh host data.
*/
@EagerSingleton
public final class Pinger implements Runnable, Service {
/**
* Constant for the number of milliseconds to wait between ping
* broadcasts. Public to make testing easier.
*/
public static final int PING_INTERVAL = 3000;
private final ScheduledExecutorService backgroundExecutor;
private final ConnectionServices connectionServices;
private final Provider<MessageRouter> messageRouter;
private final PingRequestFactory pingRequestFactory;
@Inject
public Pinger(
@Named("backgroundExecutor") ScheduledExecutorService backgroundExecutor,
ConnectionServices connectionServices,
Provider<MessageRouter> messageRouter,
PingRequestFactory pingRequestFactory) {
this.backgroundExecutor = backgroundExecutor;
this.connectionServices = connectionServices;
this.messageRouter = messageRouter;
this.pingRequestFactory = pingRequestFactory;
}
@Inject
void register(org.limewire.lifecycle.ServiceRegistry registry) {
registry.register(this);
}
public String getServiceName() {
return org.limewire.i18n.I18nMarker.marktr("Peer Listener");
}
public void initialize() {
}
public void stop() {
}
/**
* Starts the thread that continually sends broadcast pings on behalf of
* this node if it's an Ultrapeer.
*/
public void start() {
backgroundExecutor.scheduleWithFixedDelay(this, PING_INTERVAL, PING_INTERVAL, TimeUnit.MILLISECONDS);
}
/**
* Broadcasts a ping to all connections.
*/
public void run() {
if(connectionServices.isSupernode()
&& PingPongSettings.PINGS_ACTIVE.getValue()) {
PingRequest ping = pingRequestFactory.createPingRequest((byte)3);
messageRouter.get().broadcastPingRequest(ping);
}
}
}