github.com/keltia/go-ipfs@v0.3.8-0.20150909044612-210793031c63/routing/mock/centralized_server.go (about)

     1  package mockrouting
     2  
     3  import (
     4  	"math/rand"
     5  	"sync"
     6  	"time"
     7  
     8  	ds "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-datastore"
     9  	context "github.com/ipfs/go-ipfs/Godeps/_workspace/src/golang.org/x/net/context"
    10  	key "github.com/ipfs/go-ipfs/blocks/key"
    11  	peer "github.com/ipfs/go-ipfs/p2p/peer"
    12  	"github.com/ipfs/go-ipfs/util/testutil"
    13  )
    14  
    15  // server is the mockrouting.Client's private interface to the routing server
    16  type server interface {
    17  	Announce(peer.PeerInfo, key.Key) error
    18  	Providers(key.Key) []peer.PeerInfo
    19  
    20  	Server
    21  }
    22  
    23  // s is an implementation of the private server interface
    24  type s struct {
    25  	delayConf DelayConfig
    26  
    27  	lock      sync.RWMutex
    28  	providers map[key.Key]map[peer.ID]providerRecord
    29  }
    30  
    31  type providerRecord struct {
    32  	Peer    peer.PeerInfo
    33  	Created time.Time
    34  }
    35  
    36  func (rs *s) Announce(p peer.PeerInfo, k key.Key) error {
    37  	rs.lock.Lock()
    38  	defer rs.lock.Unlock()
    39  
    40  	_, ok := rs.providers[k]
    41  	if !ok {
    42  		rs.providers[k] = make(map[peer.ID]providerRecord)
    43  	}
    44  	rs.providers[k][p.ID] = providerRecord{
    45  		Created: time.Now(),
    46  		Peer:    p,
    47  	}
    48  	return nil
    49  }
    50  
    51  func (rs *s) Providers(k key.Key) []peer.PeerInfo {
    52  	rs.delayConf.Query.Wait() // before locking
    53  
    54  	rs.lock.RLock()
    55  	defer rs.lock.RUnlock()
    56  
    57  	var ret []peer.PeerInfo
    58  	records, ok := rs.providers[k]
    59  	if !ok {
    60  		return ret
    61  	}
    62  	for _, r := range records {
    63  		if time.Now().Sub(r.Created) > rs.delayConf.ValueVisibility.Get() {
    64  			ret = append(ret, r.Peer)
    65  		}
    66  	}
    67  
    68  	for i := range ret {
    69  		j := rand.Intn(i + 1)
    70  		ret[i], ret[j] = ret[j], ret[i]
    71  	}
    72  
    73  	return ret
    74  }
    75  
    76  func (rs *s) Client(p testutil.Identity) Client {
    77  	return rs.ClientWithDatastore(context.Background(), p, ds.NewMapDatastore())
    78  }
    79  
    80  func (rs *s) ClientWithDatastore(_ context.Context, p testutil.Identity, datastore ds.Datastore) Client {
    81  	return &client{
    82  		peer:      p,
    83  		datastore: ds.NewMapDatastore(),
    84  		server:    rs,
    85  	}
    86  }