providers.go 1.65 KB
Newer Older
1 2 3 4 5 6
package dht

import (
	"time"

	peer "github.com/jbenet/go-ipfs/peer"
7
	u "github.com/jbenet/go-ipfs/util"
8 9 10 11
)

type ProviderManager struct {
	providers map[u.Key][]*providerInfo
12 13 14
	newprovs  chan *addProv
	getprovs  chan *getProv
	halt      chan struct{}
15 16 17
}

type addProv struct {
18
	k   u.Key
19 20 21 22
	val *peer.Peer
}

type getProv struct {
23
	k    u.Key
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
	resp chan []*peer.Peer
}

func NewProviderManager() *ProviderManager {
	pm := new(ProviderManager)
	pm.getprovs = make(chan *getProv)
	pm.newprovs = make(chan *addProv)
	pm.providers = make(map[u.Key][]*providerInfo)
	pm.halt = make(chan struct{})
	go pm.run()
	return pm
}

func (pm *ProviderManager) run() {
	tick := time.NewTicker(time.Hour)
	for {
		select {
		case np := <-pm.newprovs:
			pi := new(providerInfo)
			pi.Creation = time.Now()
			pi.Value = np.val
			arr := pm.providers[np.k]
			pm.providers[np.k] = append(arr, pi)
		case gp := <-pm.getprovs:
			var parr []*peer.Peer
			provs := pm.providers[gp.k]
			for _, p := range provs {
				parr = append(parr, p.Value)
			}
			gp.resp <- parr
		case <-tick.C:
			for k, provs := range pm.providers {
				var filtered []*providerInfo
				for _, p := range provs {
58
					if time.Now().Sub(p.Creation) < time.Hour*24 {
59 60 61 62 63 64 65 66 67 68 69 70 71
						filtered = append(filtered, p)
					}
				}
				pm.providers[k] = filtered
			}
		case <-pm.halt:
			return
		}
	}
}

func (pm *ProviderManager) AddProvider(k u.Key, val *peer.Peer) {
	pm.newprovs <- &addProv{
72
		k:   k,
73 74 75 76 77 78 79 80 81 82 83
		val: val,
	}
}

func (pm *ProviderManager) GetProviders(k u.Key) []*peer.Peer {
	gp := new(getProv)
	gp.k = k
	gp.resp = make(chan []*peer.Peer)
	pm.getprovs <- gp
	return <-gp.resp
}
84 85 86 87

func (pm *ProviderManager) Halt() {
	pm.halt <- struct{}{}
}