// 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 ExampleTick() { p := periodicproc.Tick(time.Second, func(proc goprocess.Process) { fmt.Println("tick") }) <-time.After(3*time.Second + 500*time.Millisecond) p.Close() // Output: // tick // tick // tick }