package net.i2p.router.networkdb.kademlia;
/*
* free (adj.): unencumbered; not under the control of others
* Written by jrandom in 2003 and released into the public domain
* with no warranty of any kind, either expressed or implied.
* It probably won't make your computer catch on fire, or eat
* your children, but it might. Use at your own risk.
*
*/
import java.util.NoSuchElementException;
import java.util.Set;
import net.i2p.data.DatabaseEntry;
import net.i2p.data.Hash;
import net.i2p.router.Job;
import net.i2p.router.RouterContext;
import net.i2p.util.Log;
/**
* This extends StoreJob to fire off a FloodfillVerifyStoreJob after success.
*
* Stores through this class always request a reply.
*
*/
class FloodfillStoreJob extends StoreJob {
private final FloodfillNetworkDatabaseFacade _facade;
private static final String PROP_RI_VERIFY = "router.verifyRouterInfoStore";
/**
* Send a data structure to the floodfills
*
*/
public FloodfillStoreJob(RouterContext context, FloodfillNetworkDatabaseFacade facade, Hash key, DatabaseEntry data, Job onSuccess, Job onFailure, long timeoutMs) {
this(context, facade, key, data, onSuccess, onFailure, timeoutMs, null);
}
/**
* @param toSkip set of peer hashes of people we dont want to send the data to (e.g. we
* already know they have it). This can be null.
*/
public FloodfillStoreJob(RouterContext context, FloodfillNetworkDatabaseFacade facade, Hash key, DatabaseEntry data, Job onSuccess, Job onFailure, long timeoutMs, Set<Hash> toSkip) {
super(context, facade, key, data, onSuccess, onFailure, timeoutMs, toSkip);
_facade = facade;
}
@Override
protected int getParallelization() { return 1; }
@Override
protected int getRedundancy() { return 1; }
/**
* Send was totally successful
*/
@Override
protected void succeed() {
super.succeed();
if (_facade.isVerifyInProgress(_state.getTarget())) {
if (_log.shouldLog(Log.INFO))
_log.info("Skipping verify, one already in progress for: " + _state.getTarget());
return;
}
if (getContext().router().gracefulShutdownInProgress()) {
if (_log.shouldLog(Log.INFO))
_log.info("Skipping verify, shutdown in progress for: " + _state.getTarget());
return;
}
// Get the time stamp from the data we sent, so the Verify job can meke sure that
// it finds something stamped with that time or newer.
DatabaseEntry data = _state.getData();
boolean isRouterInfo = data.getType() == DatabaseEntry.KEY_TYPE_ROUTERINFO;
// default false since 0.9.7.1
if (isRouterInfo && !getContext().getBooleanProperty(PROP_RI_VERIFY)) {
_facade.routerInfoPublishSuccessful();
return;
}
long published = data.getDate();
// we should always have exactly one successful entry
Hash sentTo = null;
try {
sentTo = _state.getSuccessful().iterator().next();
} catch (NoSuchElementException nsee) {}
getContext().jobQueue().addJob(new FloodfillVerifyStoreJob(getContext(), _state.getTarget(),
published, isRouterInfo, sentTo, _facade));
}
@Override
public String getName() { return "Floodfill netDb store"; }
}