make bootstrap synchronous & get tests to work

This commit is contained in:
Aarsh Shah
2019-11-02 00:37:15 +08:00
parent e2842f0317
commit 7cce5bdd96
6 changed files with 106 additions and 51 deletions

View File

@@ -43,42 +43,50 @@ func init() {
}
}
type bootstrapReq struct {
errChan chan error
}
func makeBootstrapReq() *bootstrapReq {
errChan := make(chan error, 1)
return &bootstrapReq{errChan}
}
// Bootstrap i
func (dht *IpfsDHT) startBootstrapping() error {
// scan the RT table periodically & do a random walk on k-buckets that haven't been queried since the given bucket period
dht.proc.Go(func(proc process.Process) {
ctx := processctx.OnClosingContext(proc)
scanInterval := time.NewTicker(dht.bootstrapCfg.RoutingTableScanInterval)
scanInterval := time.NewTicker(dht.bootstrapCfg.BucketPeriod)
defer scanInterval.Stop()
var (
lastSelfWalk time.Time
walkSelf = true
)
// run bootstrap if option is set
if dht.triggerAutoBootstrap {
if err := dht.doBootstrap(ctx, true, &lastSelfWalk); err != nil {
logger.Warningf("bootstrap error: %s", err)
}
}
for {
if walkSelf {
walkSelf = false
err := dht.selfWalk(ctx)
if err != nil {
logger.Warningf("self walk: error: %s", err)
} else {
lastSelfWalk = time.Now()
}
}
err := dht.bootstrapBuckets(ctx)
if err != nil {
logger.Warningf("bootstrap buckets: error bootstrapping: %s", err)
}
select {
case now := <-scanInterval.C:
// It doesn't make sense to query for self unless we're _also_ going to fill out the routing table.
walkSelf = now.After(lastSelfWalk.Add(dht.bootstrapCfg.SelfQueryInterval))
case <-dht.triggerBootstrap:
walkSelf = true
walkSelf := now.After(lastSelfWalk.Add(dht.bootstrapCfg.SelfQueryInterval))
if err := dht.doBootstrap(ctx, walkSelf, &lastSelfWalk); err != nil {
logger.Warning("bootstrap error: %s", err)
}
case req := <-dht.triggerBootstrap:
logger.Infof("triggering a bootstrap: RT has %d peers", dht.routingTable.Size())
err := dht.doBootstrap(ctx, true, &lastSelfWalk)
select {
case req.errChan <- err:
close(req.errChan)
default:
}
case <-ctx.Done():
return
}
@@ -88,6 +96,22 @@ func (dht *IpfsDHT) startBootstrapping() error {
return nil
}
func (dht *IpfsDHT) doBootstrap(ctx context.Context, walkSelf bool, latestSelfWalk *time.Time) error {
if walkSelf {
if err := dht.selfWalk(ctx); err != nil {
return fmt.Errorf("self walk: error: %s", err)
} else {
*latestSelfWalk = time.Now()
}
}
if err := dht.bootstrapBuckets(ctx); err != nil {
return fmt.Errorf("bootstrap buckets: error bootstrapping: %s", err)
}
return nil
}
// bootstrapBuckets scans the routing table, and does a random walk on k-buckets that haven't been queried since the given bucket period
func (dht *IpfsDHT) bootstrapBuckets(ctx context.Context) error {
doQuery := func(bucketId int, target string, f func(context.Context) error) error {
@@ -167,9 +191,10 @@ func (dht *IpfsDHT) selfWalk(ctx context.Context) error {
//
// Note: the context is ignored.
func (dht *IpfsDHT) Bootstrap(_ context.Context) error {
// Returns an error just in case we want to do that in the future.
req := makeBootstrapReq()
select {
case dht.triggerBootstrap <- struct{}{}:
case dht.triggerBootstrap <- req:
return <-req.errChan
default:
}
return nil