java.lang.Object
net.i2p.util.StallRegistry

public class StallRegistryextends Object
Records which destinations had a streaming stall, so the router can prefer a different outbound tunnel when sending to them again.

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.

  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    private static final Map<Hash,Long>
    Last stall time for each peer
    private static final int
    Upper bound on tracked destinations.
    private static final long
    Marks older than this are dropped on the next prune.
  • Constructor Summary

    Constructors
    Modifier
    Constructor
    Description
    private
    Utility class, not intended for instantiation.
  • Method Summary

    Modifier and Type
    Method
    Description
    static void
    Drop all marks.
    static void
    markStalled(Hash remote, long now)
    Note that a stream to this destination stopped making progress.
    private static void
    prune(long now)
    Drop marks that can no longer be in effect for any cooldown a caller may use, so the map stays bounded without discarding a live signal.
    static boolean
    recentlyStalled(Hash remote, long now, long cooldownMs)
    Whether this destination was marked within the cooldown, meaning a caller may prefer a different outbound tunnel.
    static int
    Number of tracked destinations.
    static long
    stallAge(Hash remote, long now, long cooldownMs)
    How long ago this destination was marked, clamped to the cooldown.

    Methods inherited from class Object

    clone, equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Field Details

    • MAX_ENTRIES

      private static final int MAX_ENTRIES
      Upper bound on tracked destinations. Entries are tiny, but the key space is every destination this router streams to, so the map is capped and pruned rather than allowed to grow with that count.
      See Also:
    • PRUNE_AGE_MS

      private static final long PRUNE_AGE_MS
      Marks older than this are dropped on the next prune. Must exceed the longest cooldown a caller may ask about, or a mark still in effect would be collected.
      See Also:
    • _stalls

      private static final Map<Hash,Long> _stalls
      Last stall time for each peer
  • Constructor Details

    • StallRegistry

      private StallRegistry()
      Utility class, not intended for instantiation.
  • Method Details

    • markStalled

      public static void markStalled(Hash remote, long now)
      Note that a stream to this destination stopped making progress.
      Parameters:
      remote - the remote destination hash; ignored when null
      now - current time in ms
    • recentlyStalled

      public static boolean recentlyStalled(Hash remote, long now, long cooldownMs)
      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 null
      now - current time in ms
      cooldownMs - 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

      public static long stallAge(Hash remote, long now, long cooldownMs)
      How long ago this destination was marked, clamped to the cooldown.
      Parameters:
      remote - the remote destination hash; ignored when null
      now - current time in ms
      cooldownMs - how long a mark stays in effect; non-positive disables
      Returns:
      elapsed ms since the mark, or cooldownMs when unmarked, disabled, or long expired — never less than the cooldown
    • prune

      private static void prune(long now)
      Drop marks that can no longer be in effect for any cooldown a caller may use, so the map stays bounded without discarding a live signal. A pathological set of marks all younger than the prune age would survive, so the excess is dropped too rather than growing without bound.
      Parameters:
      now - current time in ms
    • 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.