- All Implemented Interfaces:
Job
This job runs continuously when enabled, selecting peers based on bandwidth tier, reachability, and version compatibility. Tests are performed by sending a DatabaseStoreMessage containing the peer's own RouterInfo back to itself through the tunnel system, measuring response times and connectivity.
Peer Selection Criteria:
- High-bandwidth tiers (O, P, X) with reachability capability
- Version 0.9.57+ for compatibility
- Configurable concurrency based on system resources
Performance Impact:
- Adaptive delays based on system load and uptime
- CPU throttling when load exceeds 80%
- Automatic timeout adjustment based on historical test times
Future Considerations:
- Evaluate necessity of peer testing in current network conditions
- Consider alternative test methods beyond RI self-messaging
- Integration with
PeerManager.selectPeers()optimization
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionprivate static classCached peer data to eliminate repeated lookups and string parsing.private classCalled when the peer's response is found.private classCalled when the peer's response times out.private classSimple selector looking for a dbStore of the peer specified.Field Summary
Modifier and TypeFieldDescriptionprivate booleanWhether to continue testing.private final LogLogger for peer tests.private PeerManagerThe peer manager we report results to.Peers tested before the random ones.private static final intDefault number of peers to test concurrently.private static final longDefault delay between peer tests.private static final intDefault timeout in milliseconds.static final StringProperty key setting how many peers are tested at once.static final StringProperty key setting the pause before a peer test starts.static final StringProperty key setting how long a peer test may take, in milliseconds.private static final longDelay during the aggressive startup phase.private static final longUptime threshold for the aggressive startup profiling phase (4 hours).private static final longDelay during steady state.private static final longDelay during the warm-up decay phase.private static final longUptime threshold for the warm-up decay phase (12 hours).Constructor Summary
ConstructorsConstructorDescriptionPeerTestJob(RouterContext context) Creates a new PeerTestJob instance and initializes required statistics.Method Summary
Modifier and TypeMethodDescriptionprivate DatabaseStoreMessagebuildMessage(RouterInfo peer, TunnelId replyTunnel, Hash replyGateway, long nonce, long expiration) Build a message to test the peer with.intAverage successful peer test time over the last minute.private TunnelInfoWhat tunnel will we get replies through?getName()Name of this job.private TunnelInfoWhat tunnel will we send the test out through?private longCalculates the delay before starting the next round of peer tests.private intDetermines the number of peers to test concurrently based on router uptime.private intDetermines the timeout for individual peer tests with automatic adjustment.intTotal average peer test time over the last hour, including slow tests.voidrunJob()Main job execution loop that performs peer testing with adaptive scheduling.voidschedulePriorityTests(List<Hash> peers) Schedule peers for priority testing (e.g., from slow tunnels).private Set<RouterInfo> Selects peers for testing based on performance and capability criteria.voidstartTesting(PeerManager manager) Starts the peer testing process.voidStops the peer testing process gracefully.private voidtestPeer(RouterInfo peer) Fire off the necessary jobs and messages to test the given peer The message is a store of the peer's RI to itself, with a reply token.private static inttierRank(ProfileOrganizer organizer, Hash peer) Selection priority for a test candidate: tier first (fast 0, high-cap 1, other 2), then staleness of the persisted tunnel-test EWMA so never-tested peers go first.Methods inherited from class JobImpl
dropped, getContext, getJobId, getMadeReadyOn, getTiming, madeReady, requeue, toStringModifier and TypeMethodDescriptionvoiddropped()Default implementation does nothing.final RouterContextThe router context that this job belongs to.longgetJobId()The unique job ID for this job.longThe timestamp when this job was last made ready for execution.The timing object for this job.voidmadeReady(long now) For JobQueue only, not for external use.protected voidrequeue(long delayMs) Requeue this job to run after the specified delay.toString()
Field Details
_log
Logger for peer tests._manager
The peer manager we report results to._keepTesting
private boolean _keepTestingWhether to continue testing._priorityPeers
DEFAULT_PEER_TEST_DELAY
private static final long DEFAULT_PEER_TEST_DELAYDefault delay between peer tests.- See Also:
PROP_PEER_TEST_DELAY
Property key setting the pause before a peer test starts.- See Also:
DEFAULT_PEER_TEST_CONCURRENCY
private static final int DEFAULT_PEER_TEST_CONCURRENCYDefault number of peers to test concurrently.- See Also:
PROP_PEER_TEST_CONCURRENCY
Property key setting how many peers are tested at once.- See Also:
DEFAULT_PEER_TEST_TIMEOUT
private static final int DEFAULT_PEER_TEST_TIMEOUTDefault timeout in milliseconds.- See Also:
PROP_PEER_TEST_TIMEOUT
Property key setting how long a peer test may take, in milliseconds.- See Also:
STARTUP_PHASE_MS
private static final long STARTUP_PHASE_MSUptime threshold for the aggressive startup profiling phase (4 hours).- See Also:
WARMUP_PHASE_MS
private static final long WARMUP_PHASE_MSUptime threshold for the warm-up decay phase (12 hours).- See Also:
STARTUP_DELAY_MS
private static final long STARTUP_DELAY_MSDelay during the aggressive startup phase.- See Also:
WARMUP_DELAY_MS
private static final long WARMUP_DELAY_MSDelay during the warm-up decay phase.- See Also:
STEADY_DELAY_MS
Constructor Details
PeerTestJob
Creates a new PeerTestJob instance and initializes required statistics.- Parameters:
context- the router context for accessing services like logging and statistics
Method Details
getAvgPeerTestTime
public int getAvgPeerTestTime()Average successful peer test time over the last minute.- Returns:
- average test time in milliseconds, or 0 if no context available
getTotalAvgPeerTestTime
public int getTotalAvgPeerTestTime()Total average peer test time over the last hour, including slow tests.- Returns:
- total average test time in milliseconds, or 0 if no context available
getPeerTestDelay
private long getPeerTestDelay()Calculates the delay before starting the next round of peer tests.Three-phase decay based on uptime:
- 0–4 hours (startup): 3s — aggressively profile all fast peers
- 4–12 hours (warm-up): 5s — ramp down while keeping data fresh
- 12+ hours (steady): 8s — maintenance cadence
User override via
PROP_PEER_TEST_DELAYis respected for the steady-state value only; startup and warm-up phases use hardcoded values.- Returns:
- delay in milliseconds before next test round
getTestTimeout
private int getTestTimeout()Determines the timeout for individual peer tests with automatic adjustment.Ensures timeout is never set below the average successful test time to avoid false timeouts during normal operation.
- Returns:
- timeout in milliseconds, adjusted if necessary
getTestConcurrency
private int getTestConcurrency()Determines the number of peers to test concurrently based on router uptime.Three-phase decay:
- 0–4 hours (startup): 4 — profile all fast peers quickly
- 4–12 hours (warm-up): 3 — ramp down
- 12+ hours (steady): 1 — maintenance cadence
Concurrency is limited to 1 when CPU load exceeds 95% to prevent system overload.
- Returns:
- number of peers to test in parallel
startTesting
Starts the peer testing process.Schedules the first test run with the configured delay. If uptime is under 3 minutes, the log notes that testing will commence shortly.
- Parameters:
manager- the peer manager to use for peer selection
stopTesting
public void stopTesting()Stops the peer testing process gracefully.The current test round will complete, but no new rounds will be scheduled.
schedulePriorityTests
getName
Name of this job.- Returns:
- the name this job is listed under in the job queue and the logs, "Test Peers"
runJob
public void runJob()Main job execution loop that performs peer testing with adaptive scheduling.Process flow:
- Check if testing should continue
- Select peers for testing based on criteria
- Test each selected peer
- Adapt next run delay based on system conditions
Adaptive Behavior:
- Skip the round and multiply delay by 5 if job lag > 2000ms
- Scale delay proportionally to lag (1 + lag/500, capped at 5 min) if job lag > 300ms or CPU load > 80%
- Normal delay otherwise
selectPeersToTest
Selects peers for testing based on performance and capability criteria.Selection Criteria:
- Priority: peers recorded from slow tunnels, tested first
- Regular: all profiled peers with a RouterInfo and version 0.9.57+, sorted by tier priority then staleness
- Excluded: Missing local RouterInfo or profile, or a version older than 0.9.57
Performance Impact:
- Uses cached lookups to minimize database queries
- Pre-parses capabilities to avoid repeated string operations
- Logs skipped peers with specific reasons for debugging
- Returns:
- set of RouterInfo structures for testing (excluding self)
testPeer
Fire off the necessary jobs and messages to test the given peer The message is a store of the peer's RI to itself, with a reply token.- Parameters:
peer- the peer to test
getOutboundTunnelId
What tunnel will we send the test out through?- Returns:
- tunnel id (or null if none are found)
getInboundTunnelId
What tunnel will we get replies through?- Returns:
- tunnel id (or null if none are found)
buildMessage
private DatabaseStoreMessage buildMessage(RouterInfo peer, TunnelId replyTunnel, Hash replyGateway, long nonce, long expiration) Build a message to test the peer with. The message is a store of the peer's RI to itself, with a reply token.- Parameters:
peer- the peer whose own RouterInfo is stored back to itreplyTunnel- the id of our inbound tunnel the reply must return throughreplyGateway- the hash of that tunnel's gateway, asked to forward the replynonce- the reply token echoed in the response so we can match it to this testexpiration- the message expiration time in ms since epoch- Returns:
- the assembled DatabaseStoreMessage carrying the reply token
tierRank
Selection priority for a test candidate: tier first (fast 0, high-cap 1, other 2), then staleness of the persisted tunnel-test EWMA so never-tested peers go first.Precomputed by
tierRank(ProfileOrganizer, Hash)rather than derived fromProfileOrganizer.isFast/isHighCapacityinside the comparator: those take the reorganize read lock, and calling them per comparison meant 4 lock acquisitions per comparison across anO(n log n)sort.- Parameters:
organizer- the profile organizer holding the fast and high-capacity setspeer- the test candidate whose tier is ranked- Returns:
- 0 for fast, 1 for high capacity, 2 for everything else