java.lang.Object
net.i2p.router.peermanager.ProfileManagerImpl
All Implemented Interfaces:
ProfileManager

public class ProfileManagerImplextends Object implements ProfileManager
Methods to update profiles. Unless otherwise noted, methods are blocking on the reorganize lock.
  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    private final RouterContext
    The router context the profiles belong to.
    private final Log
    Logger for this class.
  • Constructor Summary

    Constructors
    Constructor
    Description
    Creates the manager and its logger from the given context.
  • Method Summary

    Modifier and Type
    Method
    Description
    void
    Note that the peer was unable to reply to a db lookup - either with data or with a lookupReply redirecting the user elsewhere
    void
    Note that the local router received a db lookup from the given peer
    void
    dbLookupReply(Hash peer, int newPeers, int oldPeers, int invalid, int duplicate, long responseTimeMs)
    The peer replied to a db lookup with a redirect to other routers.
    void
    dbLookupSuccessful(Hash peer, long responseTimeMs)
    Note that the peer was able to return the valid data for a db lookup
    void
    Note that we were unable to confirm a successful send of db data to the peer, at least not within our timeout period
    void
    dbStoreReceived(Hash peer, boolean wasNewKey)
    Note that the local router received an unprompted db store from the given peer
    void
    dbStoreSent(Hash peer, long responseTimeMs)
    Note that we've confirmed a successful send of db data to the peer (though we haven't necessarily requested it again from them, so they /might/ be lying)
    void
    Note that we've verified a successful send of db data to the floodfill peer by querying another floodfill.
    private PeerProfile
    Blocking.
    private PeerProfile
    Non-blocking.
    void
    Note that the local router received a reference to the given peer, either through an explicit dbStore or in a dbLookupReply Non-blocking.
    void
    heardAbout(Hash peer, long when)
    Note that the local router received a reference to the given peer at a certain time.
    void
    Note that the router failed to send a message to the peer over any transport.
    void
    messageFailed(Hash peer, String transport)
    Note that the router failed to send a message to the peer over the transport specified.
    void
    messageReceived(Hash peer, String style, long msToReceive, int bytesRead)
    Note that the router received a message from the given peer on the specified transport.
    void
    messageSent(Hash peer, String transport, long msToSend, long bytesSent)
    Note that it took msToSend to send a message of size bytesSent to the peer over the transport.
    void
    peerLossEvent(Hash peer, float ratio)
    Record the packet-loss (retransmit) ratio measured by the transport for a peer.
    void
    tunnelDataPushed(Hash peer, long rtt, long size)
    Non-blocking.
    void
    tunnelDataPushed1m(Hash peer, long size)
    Non-blocking.
    void
    tunnelFailed(Hash peer, int pct)
    Note that the peer participated in a tunnel that failed.
    void
    tunnelJoined(Hash peer, long responseTimeMs)
    Note that the router agreed to participate in a tunnel.
    void
    tunnelLifetimePushed(Hash peer, long lifetime, long size)
    Non-blocking.
    void
    tunnelRejected(Hash peer, long responseTimeMs, int severity)
    Note that a router explicitly rejected joining a tunnel.
    void
    tunnelTestSucceeded(Hash peer, long responseTimeMs)
    Note that a tunnel that the router is participating in was successfully tested with the given round trip latency
    void
    Note that a router did not respond to a tunnel join.
    (package private) void
    Compute floodfill reliability from DBHistory.

    Methods inherited from class Object

    clone, equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait

    Methods inherited from interface ProfileManager

    commErrorOccurred
    Modifier and Type
    Method
    Description
    void
    Note that there was some sort of communication error talking with the peer.
  • Field Details

    • _log

      private final Log _log
      Logger for this class.
    • _context

      private final RouterContext _context
      The router context the profiles belong to.
  • Constructor Details

    • ProfileManagerImpl

      public ProfileManagerImpl(RouterContext context)
      Creates the manager and its logger from the given context.
      Parameters:
      context - the router context whose log manager supplies our logger
  • Method Details

    • messageSent

      public void messageSent(Hash peer, String transport, long msToSend, long bytesSent)
      Note that it took msToSend to send a message of size bytesSent to the peer over the transport. This should only be called if the transport considered the send successful. Non-blocking. Will not update the profile if we can't get the lock.

      This runs per message, so the cost is one getOrCreateProfileNonblocking — a tryReadLock() plus a map probe — and, on the rare miss, one tryWriteLock() to insert the newly created profile. Both are non-blocking, so neither can stall the transport thread behind reorganize; see peerLossEvent(Hash, float) for why the write-lock attempt is not a contention hazard. Left unchanged deliberately: the profile must exist for setLastSendSuccessful to be recorded at all, so a non-creating variant would silently drop first-contact send-success timestamps.

      Specified by:
      messageSent in interface ProfileManager
      Parameters:
      peer - hash of the peer the message was sent to
      transport - style of the transport that carried the message
      msToSend - milliseconds the send took
      bytesSent - size of the message in bytes
    • peerLossEvent

      public void peerLossEvent(Hash peer, float ratio)
      Record the packet-loss (retransmit) ratio measured by the transport for a peer. Non-blocking. Will not update the profile if we can't get the lock.

      Note on the write lock below: ProfileOrganizer.demoteIfLossy(Hash) does attempt the reorganize write lock, but it uses tryWriteLock(), which returns immediately rather than waiting, and the caller is already committed to the non-blocking contract of this method — so the message path cannot be stalled by reorganize. Frequency is also bounded well below message rate: PeerState.reportLossRatio only calls this when the retransmit ratio crosses a 5% bucket after at least ProfileOrganizer.PROP_LOSSY_MIN_PACKETS packets, so the write-lock attempt happens at most once per bucket per connection, not per packet. The check is left in place deliberately: dropping it would leave a lossy peer in the fast/high-cap tiers until the next reorganize judged it.

      Specified by:
      peerLossEvent in interface ProfileManager
      Parameters:
      peer - hash of the peer the loss was measured on
      ratio - retransmitted / transmitted packets, 0.0 = healthy
    • messageFailed

      public void messageFailed(Hash peer, String transport)
      Note that the router failed to send a message to the peer over the transport specified. Non-blocking. Will not update the profile if we can't get the lock.
      Specified by:
      messageFailed in interface ProfileManager
      Parameters:
      peer - hash of the peer the send to failed
      transport - style of the transport the send failed on
    • messageFailed

      public void messageFailed(Hash peer)
      Note that the router failed to send a message to the peer over any transport. Non-blocking. Will not update the profile if we can't get the lock.
      Specified by:
      messageFailed in interface ProfileManager
      Parameters:
      peer - hash of the peer the send to failed
    • tunnelJoined

      public void tunnelJoined(Hash peer, long responseTimeMs)
      Note that the router agreed to participate in a tunnel.
      Specified by:
      tunnelJoined in interface ProfileManager
      Parameters:
      peer - hash of the peer that agreed to join
      responseTimeMs - milliseconds the peer took to accept the request
    • tunnelRejected

      public void tunnelRejected(Hash peer, long responseTimeMs, int severity)
      Note that a router explicitly rejected joining a tunnel.
      Specified by:
      tunnelRejected in interface ProfileManager
      Parameters:
      peer - who rejected us
      responseTimeMs - response time in ms
      severity - how much the peer doesnt want to participate in the tunnel (large == more severe)
    • tunnelTimedOut

      public void tunnelTimedOut(Hash peer)
      Note that a router did not respond to a tunnel join.

      Since TunnelHistory doesn't have a timeout stat, pretend we were rejected for bandwidth reasons.

      Specified by:
      tunnelTimedOut in interface ProfileManager
      Parameters:
      peer - who rejected us
    • tunnelTestSucceeded

      public void tunnelTestSucceeded(Hash peer, long responseTimeMs)
      Note that a tunnel that the router is participating in was successfully tested with the given round trip latency

      Non-blocking. Will not update the profile if we can't get the lock.

      Specified by:
      tunnelTestSucceeded in interface ProfileManager
      Parameters:
      peer - hash of the peer on the far end of the tunnel
      responseTimeMs - round trip latency of the test in milliseconds
    • tunnelDataPushed

      public void tunnelDataPushed(Hash peer, long rtt, long size)
      Non-blocking. Will not update the profile if we can't get the lock.
      Specified by:
      tunnelDataPushed in interface ProfileManager
      Parameters:
      peer - hash of the peer participating in the tunnel
      rtt - round trip latency in milliseconds, not used in the rate accounting
      size - bytes pushed, accumulated into a long so a period total exceeding 2 GB is not truncated
    • tunnelDataPushed1m

      public void tunnelDataPushed1m(Hash peer, long size)
      Non-blocking. Will not update the profile if we can't get the lock.
      Specified by:
      tunnelDataPushed1m in interface ProfileManager
      Parameters:
      peer - hash of the peer participating in the tunnel
      size - bytes pushed during the period, normalized to a minute
    • tunnelLifetimePushed

      public void tunnelLifetimePushed(Hash peer, long lifetime, long size)
      Non-blocking. Will not update the profile if we can't get the lock.
      Specified by:
      tunnelLifetimePushed in interface ProfileManager
      Parameters:
      peer - hash of the peer participating in the tunnel
      lifetime - age of the tunnel in milliseconds
      size - bytes pushed over the lifetime of the tunnel
    • tunnelFailed

      public void tunnelFailed(Hash peer, int pct)
      Note that the peer participated in a tunnel that failed. Its failure may not have been the peer's fault however. Blame the peer with a probability of pct/100.
      Specified by:
      tunnelFailed in interface ProfileManager
      Parameters:
      peer - hash of the peer that participated in the tunnel
      pct - chance of blaming the peer for the failure, 0-100 percent
    • dbLookupSuccessful

      public void dbLookupSuccessful(Hash peer, long responseTimeMs)
      Note that the peer was able to return the valid data for a db lookup

      This will force creation of DB stats Non-blocking. Will not update the profile if we can't get the lock.

      Specified by:
      dbLookupSuccessful in interface ProfileManager
      Parameters:
      peer - hash of the peer that answered
      responseTimeMs - milliseconds the peer took to answer
    • dbLookupFailed

      public void dbLookupFailed(Hash peer)
      Note that the peer was unable to reply to a db lookup - either with data or with a lookupReply redirecting the user elsewhere

      This will force creation of DB stats Non-blocking. Will not update the profile if we can't get the lock.

      Specified by:
      dbLookupFailed in interface ProfileManager
      Parameters:
      peer - hash of the peer that did not answer
    • dbLookupReply

      public void dbLookupReply(Hash peer, int newPeers, int oldPeers, int invalid, int duplicate, long responseTimeMs)
      The peer replied to a db lookup with a redirect to other routers. The redirect list included newPeers routers we did not previously know about, oldPeers routers we already had profiles for, the given invalid routers that were unusable, and a count of duplicates we had explicitly asked them not to send but they did anyway

      Non-blocking. Will not update the profile if we can't get the lock.

      Specified by:
      dbLookupReply in interface ProfileManager
      Parameters:
      peer - hash of the peer that sent the redirect
      newPeers - redirected routers we did not previously know about
      oldPeers - redirected routers we already had profiles for
      invalid - redirected routers that were unusable
      duplicate - redirected routers we had explicitly excluded
      responseTimeMs - milliseconds the peer took to answer
    • dbLookupReceived

      public void dbLookupReceived(Hash peer)
      Note that the local router received a db lookup from the given peer

      Non-blocking. Will not update the profile if we can't get the lock.

      Specified by:
      dbLookupReceived in interface ProfileManager
      Parameters:
      peer - hash of the peer that sent the lookup to us
    • dbStoreReceived

      public void dbStoreReceived(Hash peer, boolean wasNewKey)
      Note that the local router received an unprompted db store from the given peer

      Non-blocking. Will not update the profile if we can't get the lock.

      Specified by:
      dbStoreReceived in interface ProfileManager
      Parameters:
      peer - hash of the peer that sent the store
      wasNewKey - true if the stored key was not already in our database
    • dbStoreSent

      public void dbStoreSent(Hash peer, long responseTimeMs)
      Note that we've confirmed a successful send of db data to the peer (though we haven't necessarily requested it again from them, so they /might/ be lying)

      As of 0.9.53 we update the DbResponseTime.

      This will force creation of DB stats.

      Specified by:
      dbStoreSent in interface ProfileManager
      Parameters:
      peer - hash of the peer we sent the data to
      responseTimeMs - the measured send duration in milliseconds, used as both the value and the event time
    • dbStoreSuccessful

      public void dbStoreSuccessful(Hash peer)
      Note that we've verified a successful send of db data to the floodfill peer by querying another floodfill.

      This will force creation of DB stats.

      Specified by:
      dbStoreSuccessful in interface ProfileManager
      Parameters:
      peer - hash of the peer that verified the stored data
    • updateFloodfillReliability

      void updateFloodfillReliability(PeerProfile data)
      Compute floodfill reliability from DBHistory. Updates the peer's reliability classification based on successful/failed lookup and store counts.

      Thresholds: - UNKNOWN: 0 successful lookups (probing target) - OK: 1-4 successful lookups with >=50% success rate - GOOD: >=5 successful lookups with >=80% success rate - BAD: >=5 total lookups with <50% success rate.

      Parameters:
      data - the peer profile, must have expanded DB profile
    • dbStoreFailed

      public void dbStoreFailed(Hash peer)
      Note that we were unable to confirm a successful send of db data to the peer, at least not within our timeout period

      This will force creation of DB stats.

      Specified by:
      dbStoreFailed in interface ProfileManager
      Parameters:
      peer - hash of the peer that did not verify the stored data
    • heardAbout

      public void heardAbout(Hash peer)
      Note that the local router received a reference to the given peer, either through an explicit dbStore or in a dbLookupReply Non-blocking. Will not update the profile if we can't get the lock.
      Specified by:
      heardAbout in interface ProfileManager
      Parameters:
      peer - the hash of the peer we learned about
    • heardAbout

      public void heardAbout(Hash peer, long when)
      Note that the local router received a reference to the given peer at a certain time. Only update the time if newer. Non-blocking. Will not update the profile if we can't get the lock.
      Specified by:
      heardAbout in interface ProfileManager
      Parameters:
      peer - the hash of the peer we learned about
      when - the timestamp when we learned about the peer
    • messageReceived

      public void messageReceived(Hash peer, String style, long msToReceive, int bytesRead)
      Note that the router received a message from the given peer on the specified transport. Messages received without any "from" information aren't recorded through this metric. If msToReceive is negative, there was no timing information available. Non-blocking. Will not update the profile if we can't get the lock.

      Same per-message cost profile as messageSent(Hash, String, long, long), and the same decision to leave it alone: one tryReadLock() plus a map probe on the hot path, with no lock escalation that could block the caller.

      Specified by:
      messageReceived in interface ProfileManager
      Parameters:
      peer - hash of the peer that sent the message
      style - transport style the message arrived over
      msToReceive - milliseconds the receive took, negative if untimed
      bytesRead - size of the message in bytes
    • getProfile

      private PeerProfile getProfile(Hash peer)
      Blocking. Creates a new profile if it didn't exist.
      Parameters:
      peer - the router hash whose profile is wanted
      Returns:
      non-null
    • getProfileNonblocking

      private PeerProfile getProfileNonblocking(Hash peer)
      Non-blocking. Creates a new profile if it didn't exist.
      Parameters:
      peer - the router hash whose profile is wanted
      Returns:
      null if the fetch or create would have blocked