The signal lives in core because the two layers that need it cannot see each other: apps/streaming is compiled against core and ministreaming only, so it cannot reference a router class, and the router cannot reach into a streaming connection. Core is the one place both already depend on, so the channel is this small static registry.
Keyed by the remote destination only. The streaming layer can identify its peer but not its own local destination — I2PSession does not expose it and I2PAppContext has no accessor — so a local/remote pair key could not be built from the streaming side. A stalled path is a property of the path, not of which local client happened to use it, so the shared key is also the more honest one.
Deliberately tunnel-agnostic: the registry records that a destination stalled and when; the router decides what to do, because tunnel selection is a router concern.
This is a hint, never a veto. A destination whose every tunnel is inside its cooldown must still be sent to, so the registry only answers "was this marked" and the caller is responsible for falling back.
Method Summary
All MethodsModifier and TypeMethodDescriptionstatic voidclear()Drop all marks.static voidmarkStalled(Hash remote, long now) Note that a stream to this destination stopped making progress.static booleanrecentlyStalled(Hash remote, long now, long cooldownMs) Whether this destination was marked within the cooldown, meaning a caller may prefer a different outbound tunnel.static intsize()Number of tracked destinations.static longHow long ago this destination was marked, clamped to the cooldown.
Method Details
markStalled
Note that a stream to this destination stopped making progress.- Parameters:
remote- the remote destination hash; ignored when nullnow- current time in ms
recentlyStalled
Whether this destination was marked within the cooldown, meaning a caller may prefer a different outbound tunnel.- Parameters:
remote- the remote destination hash; ignored when nullnow- current time in mscooldownMs- how long a mark stays in effect; non-positive disables- Returns:
- true if the destination was marked and the mark is still in effect
stallAge
How long ago this destination was marked, clamped to the cooldown.- Parameters:
remote- the remote destination hash; ignored when nullnow- current time in mscooldownMs- how long a mark stays in effect; non-positive disables- Returns:
- elapsed ms since the mark, or
cooldownMswhen unmarked, disabled, or long expired — never less than the cooldown
size
public static int size()Number of tracked destinations. For tests and diagnostics.- Returns:
- current entry count
clear
public static void clear()Drop all marks. For tests.