Promotion into the fast or high-capacity tier reads whatever RouterInfo the network database currently holds. A RouterInfo older than an hour is likely superseded — routers republish hourly — so promoting on one buys a tier slot that may not survive a build. ProfileOrganizer therefore holds such a promotion back and simply leaves the peer out of the tier; nothing is fetched and no network work is done on the peer's behalf.
What a cycle needs to remember is therefore only its own bounds and its two counters: the staleness threshold, the tier sizes the starvation guard compares against, how many promotions were held, and how many went ahead on a RouterInfo already known to be stale.
Locking: confined to the reorganisation write lock, which is also the only caller. Nothing here is written from a job or a selection thread.
Field Summary
FieldsModifier and TypeFieldDescription(package private) static final longMinimum gap between drains, so repeated reorgs cannot stack requests.(package private) static final intMost peers whose RouterInfo refresh may be requested in one drain.(package private) static final intCeiling on remembered peers missing a RouterInfo.(package private) static final intPeers looked up per drain when catching up on profiles loaded without a RouterInfo, giving roughly 64 lookups a minute.(package private) static final longMinimum gap between missing-RouterInfo drains, in ms.Constructor Summary
ConstructorsConstructorDescriptionA fresh cycle record: no staleness threshold, no tier floors and no deferral untilbeginCycle(long, int, int)supplies them.Method Summary
All MethodsModifier and TypeMethodDescription(package private) booleanbeginCycle(long refreshAgeMs, int fastFloor, int highCapFloor) Open a cycle, resetting the per-cycle counters.(package private) intGet the number of promotions deferred this cycle.(package private) intGet the fast-tier size at which promotion may be deferred.(package private) intPeers dropped because the queue or the interval was full.(package private) intPeers waiting for a lookup.(package private) intPeers dropped because the missing-RouterInfo set was already at its cap.(package private) intPeers still waiting for their RouterInfo to be requested.(package private) intGet the high-capacity size at which promotion may be deferred.(package private) booleanTest whether promotions are being held back this cycle.(package private) booleanmayDrainAddressRefreshes(long now) Whether enough time has passed since the last drain to issue another batch.(package private) booleanmayDrainMissingRouterInfo(long now) Whether enough time has passed to drain the missing-RouterInfo set.(package private) voidRecord a promotion held back because of a stale RouterInfo.(package private) booleannoteMissingRouterInfo(Hash peer) Note that a stored profile was loaded for a peer the netdb cannot resolve.(package private) voidRecord a promotion the starvation guard let through on a RouterInfo that is already known to be stale.(package private) intThe promotions the starvation guard let through on a RouterInfo that was already known to be stale.(package private) longGet the staleness threshold applied this cycle.(package private) booleanrequestAddressRefresh(Hash peer) Ask for a RouterInfo lookup for a peer held out of the tiers for want of a usable address.takeAddressRefreshBatch(long now) Hand over the queued peers, oldest first, clearing the queue.takeMissingRouterInfoBatch(long now) Hand over up to one batch of peers to look up, removing them from the set.
Field Details
MAX_ADDRESS_REFRESHES
static final int MAX_ADDRESS_REFRESHESMost peers whose RouterInfo refresh may be requested in one drain.- See Also:
MISSING_ROUTERINFO_BATCH
static final int MISSING_ROUTERINFO_BATCHPeers looked up per drain when catching up on profiles loaded without a RouterInfo, giving roughly 64 lookups a minute.Faster than
MAX_ADDRESS_REFRESHESon purpose. That cap is sized for held promotion candidates, a trickle of a few per reorganize; a router coming back from downtime may hold thousands of profiles whose RouterInfo has since expired, and at 16 a minute they would stay unusable for hours. Each lookup is a fire-and-forgetlookupRouterInfo, and the netdb negatively caches known-dead keys, so peers that never come back cost little on repeat.- See Also:
MISSING_ROUTERINFO_MIN_INTERVAL_MS
static final long MISSING_ROUTERINFO_MIN_INTERVAL_MSMinimum gap between missing-RouterInfo drains, in ms.Sets the rate at
MISSING_ROUTERINFO_BATCHper interval, about 64 a minute, so a couple of thousand profiles take roughly half an hour to recover.- See Also:
MAX_MISSING_ROUTERINFO
static final int MAX_MISSING_ROUTERINFOCeiling on remembered peers missing a RouterInfo.The set is a recovery list, not a backlog to be worked off exhaustively. Past this size the extra peers are not worth the memory and the lookups: they are peers the netdb has already stopped telling us about.
- See Also:
ADDRESS_REFRESH_MIN_INTERVAL_MS
static final long ADDRESS_REFRESH_MIN_INTERVAL_MSMinimum gap between drains, so repeated reorgs cannot stack requests.- See Also:
Constructor Details
RouterInfoRefresher
RouterInfoRefresher()A fresh cycle record: no staleness threshold, no tier floors and no deferral untilbeginCycle(long, int, int)supplies them.
Method Details
beginCycle
boolean beginCycle(long refreshAgeMs, int fastFloor, int highCapFloor) Open a cycle, resetting the per-cycle counters.There is nothing to stagger here. The earlier startup grace period, quota and queue rotation only ever throttled how many lookups a cycle could issue; with no lookup to issue, each cycle now judges every candidate, and a fresh cycle resets the counters so they report one cycle rather than the life of the router.
- Parameters:
refreshAgeMs- staleness threshold for this cycle, or <= 0 to disablefastFloor- fast-tier size at or above which a promotion may be held backhighCapFloor- high-capacity tier size at or above which a promotion may be held back- Returns:
- whether promotions are being held back this cycle
noteDeferral
void noteDeferral()Record a promotion held back because of a stale RouterInfo. One integer increment: this runs on the promotion path, once per held tier insert, and has to stay cheap enough for the loop that calls it.noteStalePromotion
void noteStalePromotion()Record a promotion the starvation guard let through on a RouterInfo that is already known to be stale. This is the population thepeer.promotedStaleRouterInfostat reports.refreshAgeMs
long refreshAgeMs()Get the staleness threshold applied this cycle.- Returns:
- the staleness threshold in force this cycle, in ms
isDeferring
boolean isDeferring()Test whether promotions are being held back this cycle.- Returns:
- whether promotions are being held back this cycle
fastFloor
int fastFloor()Get the fast-tier size at which promotion may be deferred.- Returns:
- fast-tier size at or above which a promotion may be held back
highCapFloor
int highCapFloor()Get the high-capacity size at which promotion may be deferred.- Returns:
- high-capacity size at or above which a promotion may be held back
deferredCount
int deferredCount()Get the number of promotions deferred this cycle.- Returns:
- promotions held back this cycle, counted across both tiers
promotedStaleCount
int promotedStaleCount()The promotions the starvation guard let through on a RouterInfo that was already known to be stale.- Returns:
- stale promotions counted since the last beginCycle()
requestAddressRefresh
Ask for a RouterInfo lookup for a peer held out of the tiers for want of a usable address.A held peer cannot be refreshed directly - that is precisely why it is held, since it has no address to send to - so the only way to re-qualify it is an iterative lookup via other routers. This only records the request;
takeAddressRefreshBatch(long)issues it, because the scan that fills this queue runs under the reorganize write lock and must not do network work there.Bounded by
MAX_ADDRESS_REFRESHES, so a scan over thousands of profiles cannot enqueue thousands of lookups.- Parameters:
peer- the held peer- Returns:
- true if the request was recorded
mayDrainAddressRefreshes
boolean mayDrainAddressRefreshes(long now) Whether enough time has passed since the last drain to issue another batch.- Parameters:
now- current time in milliseconds- Returns:
- true if a drain may run
takeAddressRefreshBatch
getAddressRefreshDropped
int getAddressRefreshDropped()Peers dropped because the queue or the interval was full.- Returns:
- the count of peers dropped because the queue or the interval was full
getAddressRefreshPending
int getAddressRefreshPending()Peers waiting for a lookup.- Returns:
- the count of peers waiting for a lookup
noteMissingRouterInfo
Note that a stored profile was loaded for a peer the netdb cannot resolve.Until the RouterInfo comes back the profile is inert: peer selection needs an address to send to, and
ProfileOrganizer.isExcludedFromProfiling(Hash)declines to profile a peer with no RouterInfo. The capacity, latency and acceptance history in the file is then retained but unused, which only pays off if something goes and fetches the RouterInfo again.- Parameters:
peer- the peer whose profile was loaded- Returns:
- true if the peer was recorded, false if the set was already full
mayDrainMissingRouterInfo
boolean mayDrainMissingRouterInfo(long now) Whether enough time has passed to drain the missing-RouterInfo set.- Parameters:
now- current time in milliseconds- Returns:
- true if the drain interval has elapsed
takeMissingRouterInfoBatch
getMissingRouterInfoDropped
int getMissingRouterInfoDropped()Peers dropped because the missing-RouterInfo set was already at its cap.- Returns:
- the count of peers dropped because the missing-RouterInfo set was full
getMissingRouterInfoPending
int getMissingRouterInfoPending()Peers still waiting for their RouterInfo to be requested.- Returns:
- the count of peers still waiting for their RouterInfo to be requested