offline.go 1.8 KB
Newer Older
Jeromy's avatar
Jeromy committed
1 2 3
// package offline implements an object that implements the exchange
// interface but returns nil values to every request.
package offline
4 5

import (
6 7 8 9 10
	context "github.com/ipfs/go-ipfs/Godeps/_workspace/src/golang.org/x/net/context"
	blocks "github.com/ipfs/go-ipfs/blocks"
	"github.com/ipfs/go-ipfs/blocks/blockstore"
	exchange "github.com/ipfs/go-ipfs/exchange"
	u "github.com/ipfs/go-ipfs/util"
11 12
)

13 14
func Exchange(bs blockstore.Blockstore) exchange.Interface {
	return &offlineExchange{bs: bs}
15 16 17 18
}

// offlineExchange implements the Exchange interface but doesn't return blocks.
// For use in offline mode.
19 20 21
type offlineExchange struct {
	bs blockstore.Blockstore
}
22

Jeromy's avatar
Jeromy committed
23
// GetBlock returns nil to signal that a block could not be retrieved for the
24 25
// given key.
// NB: This function may return before the timeout expires.
26 27
func (e *offlineExchange) GetBlock(_ context.Context, k u.Key) (*blocks.Block, error) {
	return e.bs.Get(k)
28 29 30
}

// HasBlock always returns nil.
31 32
func (e *offlineExchange) HasBlock(_ context.Context, b *blocks.Block) error {
	return e.bs.Put(b)
33
}
34 35 36

// Close always returns nil.
func (_ *offlineExchange) Close() error {
37 38
	// NB: exchange doesn't own the blockstore's underlying datastore, so it is
	// not responsible for closing it.
39 40
	return nil
}
Jeromy's avatar
Jeromy committed
41

42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
func (e *offlineExchange) GetBlocks(ctx context.Context, ks []u.Key) (<-chan *blocks.Block, error) {
	out := make(chan *blocks.Block, 0)
	go func() {
		defer close(out)
		var misses []u.Key
		for _, k := range ks {
			hit, err := e.bs.Get(k)
			if err != nil {
				misses = append(misses, k)
				// a long line of misses should abort when context is cancelled.
				select {
				// TODO case send misses down channel
				case <-ctx.Done():
					return
				default:
					continue
				}
			}
			select {
			case out <- hit:
			case <-ctx.Done():
				return
			}
		}
	}()
	return out, nil
Jeromy's avatar
Jeromy committed
68
}