// Bootstrap kicks off IpfsNode bootstrapping. This function will periodically // check the number of open connections and -- if there are too few -- initiate // connections to well-known bootstrap peers. It also kicks off subsystem // bootstrapping (i.e. routing). func Bootstrap(n *IpfsNode, cfg BootstrapConfig) (io.Closer, error) { // make a signal to wait for one bootstrap round to complete. doneWithRound := make(chan struct{}) // the periodic bootstrap function -- the connection supervisor periodic := func(worker goprocess.Process) { ctx := procctx.OnClosingContext(worker) defer log.EventBegin(ctx, "periodicBootstrap", n.Identity).Done() if err := bootstrapRound(ctx, n.PeerHost, cfg); err != nil { log.Event(ctx, "bootstrapError", n.Identity, lgbl.Error(err)) log.Debugf("%s bootstrap error: %s", n.Identity, err) } <-doneWithRound } // kick off the node's periodic bootstrapping proc := periodicproc.Tick(cfg.Period, periodic) proc.Go(periodic) // run one right now. // kick off Routing.Bootstrap if n.Routing != nil { ctx := procctx.OnClosingContext(proc) if err := n.Routing.Bootstrap(ctx); err != nil { proc.Close() return nil, err } } doneWithRound <- struct{}{} close(doneWithRound) // it no longer blocks periodic return proc, nil }
func (rp *Republisher) republishEntries(p goprocess.Process) error { ctx, cancel := context.WithCancel(gpctx.OnClosingContext(p)) defer cancel() for id, _ := range rp.entries { log.Debugf("republishing ipns entry for %s", id) priv := rp.ps.PrivKey(id) // Look for it locally only _, ipnskey := namesys.IpnsKeysForID(id) p, seq, err := rp.getLastVal(ipnskey) if err != nil { if err == errNoEntry { continue } return err } // update record with same sequence number eol := time.Now().Add(rp.RecordLifetime) err = namesys.PutRecordToRouting(ctx, priv, p, seq, eol, rp.r, id) if err != nil { return err } } return nil }
func (bs *Bitswap) provideWorker(px process.Process) { limit := make(chan struct{}, provideWorkerMax) limitedGoProvide := func(k *cid.Cid, wid int) { defer func() { // replace token when done <-limit }() ev := logging.LoggableMap{"ID": wid} ctx := procctx.OnClosingContext(px) // derive ctx from px defer log.EventBegin(ctx, "Bitswap.ProvideWorker.Work", ev, k).Done() ctx, cancel := context.WithTimeout(ctx, provideTimeout) // timeout ctx defer cancel() if err := bs.network.Provide(ctx, k); err != nil { log.Warning(err) } } // worker spawner, reads from bs.provideKeys until it closes, spawning a // _ratelimited_ number of workers to handle each key. for wid := 2; ; wid++ { ev := logging.LoggableMap{"ID": 1} log.Event(procctx.OnClosingContext(px), "Bitswap.ProvideWorker.Loop", ev) select { case <-px.Closing(): return case k, ok := <-bs.provideKeys: if !ok { log.Debug("provideKeys channel closed") return } select { case <-px.Closing(): return case limit <- struct{}{}: go limitedGoProvide(k, wid) } } } }