github.com/keltia/go-ipfs@v0.3.8-0.20150909044612-210793031c63/exchange/reprovide/reprovide.go (about)

     1  package reprovide
     2  
     3  import (
     4  	"fmt"
     5  	"time"
     6  
     7  	backoff "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/cenkalti/backoff"
     8  	context "github.com/ipfs/go-ipfs/Godeps/_workspace/src/golang.org/x/net/context"
     9  	blocks "github.com/ipfs/go-ipfs/blocks/blockstore"
    10  	routing "github.com/ipfs/go-ipfs/routing"
    11  	eventlog "github.com/ipfs/go-ipfs/thirdparty/eventlog"
    12  )
    13  
    14  var log = eventlog.Logger("reprovider")
    15  
    16  type Reprovider struct {
    17  	// The routing system to provide values through
    18  	rsys routing.IpfsRouting
    19  
    20  	// The backing store for blocks to be provided
    21  	bstore blocks.Blockstore
    22  }
    23  
    24  func NewReprovider(rsys routing.IpfsRouting, bstore blocks.Blockstore) *Reprovider {
    25  	return &Reprovider{
    26  		rsys:   rsys,
    27  		bstore: bstore,
    28  	}
    29  }
    30  
    31  func (rp *Reprovider) ProvideEvery(ctx context.Context, tick time.Duration) {
    32  	// dont reprovide immediately.
    33  	// may have just started the daemon and shutting it down immediately.
    34  	// probability( up another minute | uptime ) increases with uptime.
    35  	after := time.After(time.Minute)
    36  	for {
    37  		select {
    38  		case <-ctx.Done():
    39  			return
    40  		case <-after:
    41  			err := rp.Reprovide(ctx)
    42  			if err != nil {
    43  				log.Debug(err)
    44  			}
    45  			after = time.After(tick)
    46  		}
    47  	}
    48  }
    49  
    50  func (rp *Reprovider) Reprovide(ctx context.Context) error {
    51  	keychan, err := rp.bstore.AllKeysChan(ctx)
    52  	if err != nil {
    53  		return fmt.Errorf("Failed to get key chan from blockstore: %s", err)
    54  	}
    55  	for k := range keychan {
    56  		op := func() error {
    57  			err := rp.rsys.Provide(ctx, k)
    58  			if err != nil {
    59  				log.Debugf("Failed to provide key: %s", err)
    60  			}
    61  			return err
    62  		}
    63  
    64  		// TODO: this backoff library does not respect our context, we should
    65  		// eventually work contexts into it. low priority.
    66  		err := backoff.Retry(op, backoff.NewExponentialBackOff())
    67  		if err != nil {
    68  			log.Debugf("Providing failed after number of retries: %s", err)
    69  			return err
    70  		}
    71  	}
    72  	return nil
    73  }