| Safe Haskell | None |
|---|---|
| Language | GHC2021 |
LibP2P.Switch.Dial
Description
Dial logic for the Switch.
Implements connection reuse, exponential backoff, dial deduplication, and parallel staggered dialing (Happy Eyeballs, RFC 8305).
Dial flow: 1. Check connection pool for existing Open connection 2. Check per-peer backoff (reject if recently failed) 3. Deduplication: join pending dial if another thread is already dialing 4. Select transport per address, staggered parallel dial 5. Upgrade first successful raw connection 6. Add to pool / record backoff on failure
Synopsis
- dial :: Switch -> PeerId -> [Multiaddr] -> IO (Either DialError Connection)
- data DialOpts = DialOpts {
- doForceDirect :: !Bool
- doUpgradeAsClient :: !Bool
- defaultDialOpts :: DialOpts
- dialWith :: Switch -> DialOpts -> PeerId -> [Multiaddr] -> IO (Either DialError Connection)
- checkBackoff :: TVar (Map PeerId BackoffEntry) -> PeerId -> IO (Either DialError ())
- recordBackoff :: TVar (Map PeerId BackoffEntry) -> PeerId -> IO ()
- clearBackoff :: TVar (Map PeerId BackoffEntry) -> PeerId -> IO ()
- initialBackoffSeconds :: NominalDiffTime
- maxBackoffSeconds :: NominalDiffTime
- staggerDelayUs :: Int
Main entry point
dial :: Switch -> PeerId -> [Multiaddr] -> IO (Either DialError Connection) Source #
Dial a peer, reusing existing connections or establishing new ones.
Implements the full dial flow: 1. Pool reuse: return existing Open connection if available 2. Backoff check: reject if peer recently failed 3. Deduplication: coalesce concurrent dials to same peer via TMVar 4. Staggered parallel dial with 250ms delay (Happy Eyeballs) 5. First success: upgrade, add to pool, return 6. All fail: record backoff, return error
Dial options
Per-dial options.
Mirrors the two orthogonal context values go-libp2p threads through a
dial: network.WithForceDirectDial and network.WithSimultaneousConnect,
which its hole puncher sets together.
Constructors
| DialOpts | |
Fields
| |
defaultDialOpts :: DialOpts Source #
Ordinary dial: reuse pooled connections, honour backoff, act as client.
dialWith :: Switch -> DialOpts -> PeerId -> [Multiaddr] -> IO (Either DialError Connection) Source #
Dial a peer under explicit options.
A force-direct dial skips steps 1-3 entirely. Skipping deduplication is required, not incidental: DCUtR calls its dialer once per address so that every address is attempted at the same moment, and a shared pending-dial TMVar carries one result for all waiters, so joining it would collapse those attempts into a single address. Backoff is still *recorded* on failure, as go-libp2p does.
Backoff management
checkBackoff :: TVar (Map PeerId BackoffEntry) -> PeerId -> IO (Either DialError ()) Source #
Check if a peer is currently in dial backoff. Returns Right () if no backoff is active or the backoff has expired. Expired entries are cleaned up atomically.
recordBackoff :: TVar (Map PeerId BackoffEntry) -> PeerId -> IO () Source #
Record a backoff after a failed dial. First failure: 5s. Each subsequent: duration * 2, capped at 300s. Backoff formula: min(initialBackoff * 2^(attempts-1), maxBackoff)
clearBackoff :: TVar (Map PeerId BackoffEntry) -> PeerId -> IO () Source #
Clear backoff for a peer (called on successful connection).
Constants (exported for testing)
initialBackoffSeconds :: NominalDiffTime Source #
Initial backoff duration after first failure: 5 seconds.
maxBackoffSeconds :: NominalDiffTime Source #
Maximum backoff duration: 300 seconds (5 minutes).
staggerDelayUs :: Int Source #
Stagger delay between parallel dial attempts: 250ms (RFC 8305).