package backoff
import (
"context"
"sync"
"time"
"github.com/libp2p/go-libp2p/core/host"
"github.com/libp2p/go-libp2p/core/peer"
lru "github.com/hashicorp/golang-lru/v2"
)
type BackoffConnector struct {
cache *lru .TwoQueueCache [peer .ID , *connCacheData ]
host host .Host
connTryDur time .Duration
backoff BackoffFactory
mux sync .Mutex
}
func NewBackoffConnector (h host .Host , cacheSize int , connectionTryDuration time .Duration , backoff BackoffFactory ) (*BackoffConnector , error ) {
cache , err := lru .New2Q [peer .ID , *connCacheData ](cacheSize )
if err != nil {
return nil , err
}
return &BackoffConnector {
cache : cache ,
host : h ,
connTryDur : connectionTryDuration ,
backoff : backoff ,
}, nil
}
type connCacheData struct {
nextTry time .Time
strat BackoffStrategy
}
func (c *BackoffConnector ) Connect (ctx context .Context , peerCh <-chan peer .AddrInfo ) {
for {
select {
case pi , ok := <- peerCh :
if !ok {
return
}
if pi .ID == c .host .ID () || pi .ID == "" {
continue
}
c .mux .Lock ()
var cachedPeer *connCacheData
if tv , ok := c .cache .Get (pi .ID ); ok {
now := time .Now ()
if now .Before (tv .nextTry ) {
c .mux .Unlock ()
continue
}
tv .nextTry = now .Add (tv .strat .Delay ())
} else {
cachedPeer = &connCacheData {strat : c .backoff ()}
cachedPeer .nextTry = time .Now ().Add (cachedPeer .strat .Delay ())
c .cache .Add (pi .ID , cachedPeer )
}
c .mux .Unlock ()
go func (pi peer .AddrInfo ) {
ctx , cancel := context .WithTimeout (ctx , c .connTryDur )
defer cancel ()
err := c .host .Connect (ctx , pi )
if err != nil {
log .Debugf ("Error connecting to pubsub peer %s: %s" , pi .ID , err .Error())
return
}
}(pi )
case <- ctx .Done ():
log .Infof ("discovery: backoff connector context error %v" , ctx .Err ())
return
}
}
}
The pages are generated with Golds v0.8.2 . (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds .