NetDB: Wake up FloodfillMonitor when ff setting changes,

so it will take effect immediately, and log in event log.
Don't queue multiple FloodJobs after changes
This commit is contained in:
zzz
2018-03-10 12:30:17 +00:00
parent 4bcb1d27e4
commit fa85c0c50b
3 changed files with 34 additions and 11 deletions

View File

@ -109,9 +109,8 @@ public class ConfigAdvancedHandler extends FormHandler {
FloodfillNetworkDatabaseFacade fndf = (FloodfillNetworkDatabaseFacade) _context.netDb(); FloodfillNetworkDatabaseFacade fndf = (FloodfillNetworkDatabaseFacade) _context.netDb();
boolean wasFF = fndf.floodfillEnabled(); boolean wasFF = fndf.floodfillEnabled();
boolean isFF = _ff.equals("true"); boolean isFF = _ff.equals("true");
// this will rebuild the RI, log in the event log, etc.
fndf.setFloodfillEnabled(isFF); fndf.setFloodfillEnabled(isFF);
if (wasFF != isFF)
_context.router().rebuildRouterInfo();
} }
if (saved) if (saved)
addFormNotice(_t("Configuration saved successfully")); addFormNotice(_t("Configuration saved successfully"));

View File

@ -31,6 +31,7 @@ class FloodfillMonitorJob extends JobImpl {
private final Log _log; private final Log _log;
private final FloodfillNetworkDatabaseFacade _facade; private final FloodfillNetworkDatabaseFacade _facade;
private long _lastChanged; private long _lastChanged;
private boolean _deferredFlood;
private static final int REQUEUE_DELAY = 60*60*1000; private static final int REQUEUE_DELAY = 60*60*1000;
private static final long MIN_UPTIME = 2*60*60*1000; private static final long MIN_UPTIME = 2*60*60*1000;
@ -48,10 +49,10 @@ class FloodfillMonitorJob extends JobImpl {
public String getName() { return "Monitor the floodfill pool"; } public String getName() { return "Monitor the floodfill pool"; }
public void runJob() { public synchronized void runJob() {
boolean wasFF = _facade.floodfillEnabled(); boolean wasFF = _facade.floodfillEnabled();
boolean ff = shouldBeFloodfill(); boolean ff = shouldBeFloodfill();
_facade.setFloodfillEnabled(ff); _facade.setFloodfillEnabledFromMonitor(ff);
if (ff != wasFF) { if (ff != wasFF) {
if (ff) { if (ff) {
getContext().router().eventLog().addEvent(EventLog.BECAME_FLOODFILL); getContext().router().eventLog().addEvent(EventLog.BECAME_FLOODFILL);
@ -60,12 +61,15 @@ class FloodfillMonitorJob extends JobImpl {
} }
getContext().router().rebuildRouterInfo(true); getContext().router().rebuildRouterInfo(true);
Job routerInfoFlood = new FloodfillRouterInfoFloodJob(getContext(), _facade); Job routerInfoFlood = new FloodfillRouterInfoFloodJob(getContext(), _facade);
if(getContext().router().getUptime() < 5*60*1000) { if (getContext().router().getUptime() < 5*60*1000) {
// Needed to prevent race if router.floodfillParticipant=true (not auto) if (!_deferredFlood) {
routerInfoFlood.getTiming().setStartAfter(getContext().clock().now() + 5*60*1000); // Needed to prevent race if router.floodfillParticipant=true (not auto)
getContext().jobQueue().addJob(routerInfoFlood); // Don't queue multiples
if(_log.shouldLog(Log.DEBUG)) { _deferredFlood = true;
_log.logAlways(Log.DEBUG, "Deferring our FloodfillRouterInfoFloodJob run because of low uptime."); routerInfoFlood.getTiming().setStartAfter(getContext().clock().now() + 5*60*1000);
getContext().jobQueue().addJob(routerInfoFlood);
if (_log.shouldLog(Log.DEBUG))
_log.logAlways(Log.DEBUG, "Deferring our FloodfillRouterInfoFloodJob run because of low uptime.");
} }
} else { } else {
routerInfoFlood.runJob(); routerInfoFlood.runJob();

View File

@ -33,6 +33,7 @@ public class FloodfillNetworkDatabaseFacade extends KademliaNetworkDatabaseFacad
private final Set<Hash> _verifiesInProgress; private final Set<Hash> _verifiesInProgress;
private FloodThrottler _floodThrottler; private FloodThrottler _floodThrottler;
private LookupThrottler _lookupThrottler; private LookupThrottler _lookupThrottler;
private final Job _ffMonitor;
/** /**
* This is the flood redundancy. Entries are * This is the flood redundancy. Entries are
@ -68,12 +69,13 @@ public class FloodfillNetworkDatabaseFacade extends KademliaNetworkDatabaseFacad
_context.statManager().createRateStat("netDb.republishQuantity", "How many peers do we need to send a found leaseSet to?", "NetworkDatabase", new long[] { 10*60*1000l, 60*60*1000l, 3*60*60*1000l, 24*60*60*1000l }); _context.statManager().createRateStat("netDb.republishQuantity", "How many peers do we need to send a found leaseSet to?", "NetworkDatabase", new long[] { 10*60*1000l, 60*60*1000l, 3*60*60*1000l, 24*60*60*1000l });
// for ISJ // for ISJ
_context.statManager().createRateStat("netDb.RILookupDirect", "Was an iterative RI lookup sent directly?", "NetworkDatabase", new long[] { 60*60*1000 }); _context.statManager().createRateStat("netDb.RILookupDirect", "Was an iterative RI lookup sent directly?", "NetworkDatabase", new long[] { 60*60*1000 });
_ffMonitor = new FloodfillMonitorJob(_context, this);
} }
@Override @Override
public synchronized void startup() { public synchronized void startup() {
super.startup(); super.startup();
_context.jobQueue().addJob(new FloodfillMonitorJob(_context, this)); _context.jobQueue().addJob(_ffMonitor);
_lookupThrottler = new LookupThrottler(); _lookupThrottler = new LookupThrottler();
// refresh old routers // refresh old routers
@ -114,6 +116,7 @@ public class FloodfillNetworkDatabaseFacade extends KademliaNetworkDatabaseFacad
} catch (InterruptedException ie) {} } catch (InterruptedException ie) {}
} }
} }
_context.jobQueue().removeJob(_ffMonitor);
super.shutdown(); super.shutdown();
} }
@ -278,7 +281,24 @@ public class FloodfillNetworkDatabaseFacade extends KademliaNetworkDatabaseFacad
@Override @Override
protected PeerSelector createPeerSelector() { return new FloodfillPeerSelector(_context); } protected PeerSelector createPeerSelector() { return new FloodfillPeerSelector(_context); }
/**
* Public, called from console. This wakes up the floodfill monitor,
* which will rebuild the RI and log in the event log,
* and call setFloodfillEnabledFromMonitor which really sets it.
*/
public synchronized void setFloodfillEnabled(boolean yes) { public synchronized void setFloodfillEnabled(boolean yes) {
if (yes != _floodfillEnabled) {
_context.jobQueue().removeJob(_ffMonitor);
_ffMonitor.getTiming().setStartAfter(_context.clock().now() + 1000);
_context.jobQueue().addJob(_ffMonitor);
}
}
/**
* Package private, called from FloodfillMonitorJob. This does not wake up the floodfill monitor.
* @since 0.9.34
*/
synchronized void setFloodfillEnabledFromMonitor(boolean yes) {
_floodfillEnabled = yes; _floodfillEnabled = yes;
if (yes && _floodThrottler == null) { if (yes && _floodThrottler == null) {
_floodThrottler = new FloodThrottler(); _floodThrottler = new FloodThrottler();