Skip to content

Commit 523a9b8

Browse files
authored
Merge pull request #593 from alanshaw/feat/set-provider-mgr-options
feat: set provider manager options
2 parents 21b38cc + 1d696d1 commit 523a9b8

File tree

4 files changed

+81
-14
lines changed

4 files changed

+81
-14
lines changed

dht.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,11 @@ func makeDHT(ctx context.Context, h host.Host, cfg config) (*IpfsDHT, error) {
279279
// the DHT context should be done when the process is closed
280280
dht.ctx = goprocessctx.WithProcessClosing(ctxTags, dht.proc)
281281

282-
dht.ProviderManager = providers.NewProviderManager(dht.ctx, h.ID(), cfg.datastore)
282+
pm, err := providers.NewProviderManager(dht.ctx, h.ID(), cfg.datastore, cfg.providersOptions...)
283+
if err != nil {
284+
return nil, err
285+
}
286+
dht.ProviderManager = pm
283287

284288
return dht, nil
285289
}

dht_options.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"github.com/libp2p/go-libp2p-core/network"
1212
"github.com/libp2p/go-libp2p-core/peer"
1313
"github.com/libp2p/go-libp2p-core/protocol"
14+
"github.com/libp2p/go-libp2p-kad-dht/providers"
1415
record "github.com/libp2p/go-libp2p-record"
1516
)
1617

@@ -45,6 +46,7 @@ type config struct {
4546
maxRecordAge time.Duration
4647
enableProviders bool
4748
enableValues bool
49+
providersOptions []providers.Option
4850
queryPeerFilter QueryFilterFunc
4951

5052
routingTable struct {
@@ -348,6 +350,18 @@ func DisableValues() Option {
348350
}
349351
}
350352

353+
// ProvidersOptions are options passed directly to the provider manager.
354+
//
355+
// The provider manager adds and gets provider records from the datastore, cahing
356+
// them in between. These options are passed to the provider manager allowing
357+
// customisation of things like the GC interval and cache implementation.
358+
func ProvidersOptions(opts []providers.Option) Option {
359+
return func(c *config) error {
360+
c.providersOptions = opts
361+
return nil
362+
}
363+
}
364+
351365
// QueryFilter sets a function that approves which peers may be dialed in a query
352366
func QueryFilter(filter QueryFilterFunc) Option {
353367
return func(c *config) error {

providers/providers_manager.go

Lines changed: 38 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ var log = logging.Logger("providers")
3535
type ProviderManager struct {
3636
// all non channel fields are meant to be accessed only within
3737
// the run method
38-
cache *lru.LRU
38+
cache lru.LRUCache
3939
dstore *autobatch.Datastore
4040

4141
newprovs chan *addProv
@@ -45,6 +45,36 @@ type ProviderManager struct {
4545
cleanupInterval time.Duration
4646
}
4747

48+
// Option is a function that sets a provider manager option.
49+
type Option func(*ProviderManager) error
50+
51+
func (pm *ProviderManager) applyOptions(opts ...Option) error {
52+
for i, opt := range opts {
53+
if err := opt(pm); err != nil {
54+
return fmt.Errorf("provider manager option %d failed: %s", i, err)
55+
}
56+
}
57+
return nil
58+
}
59+
60+
// CleanupInterval sets the time between GC runs.
61+
// Defaults to 1h.
62+
func CleanupInterval(d time.Duration) Option {
63+
return func(pm *ProviderManager) error {
64+
pm.cleanupInterval = d
65+
return nil
66+
}
67+
}
68+
69+
// Cache sets the LRU cache implementation.
70+
// Defaults to a simple LRU cache.
71+
func Cache(c lru.LRUCache) Option {
72+
return func(pm *ProviderManager) error {
73+
pm.cache = c
74+
return nil
75+
}
76+
}
77+
4878
type addProv struct {
4979
key []byte
5080
val peer.ID
@@ -56,22 +86,23 @@ type getProv struct {
5686
}
5787

5888
// NewProviderManager constructor
59-
func NewProviderManager(ctx context.Context, local peer.ID, dstore ds.Batching) *ProviderManager {
89+
func NewProviderManager(ctx context.Context, local peer.ID, dstore ds.Batching, opts ...Option) (*ProviderManager, error) {
6090
pm := new(ProviderManager)
6191
pm.getprovs = make(chan *getProv)
6292
pm.newprovs = make(chan *addProv)
6393
pm.dstore = autobatch.NewAutoBatching(dstore, batchBufferSize)
6494
cache, err := lru.NewLRU(lruCacheSize, nil)
6595
if err != nil {
66-
panic(err) //only happens if negative value is passed to lru constructor
96+
return nil, err
6797
}
6898
pm.cache = cache
69-
70-
pm.proc = goprocessctx.WithContext(ctx)
7199
pm.cleanupInterval = defaultCleanupInterval
100+
if err := pm.applyOptions(opts...); err != nil {
101+
return nil, err
102+
}
103+
pm.proc = goprocessctx.WithContext(ctx)
72104
pm.proc.Go(pm.run)
73-
74-
return pm
105+
return pm, nil
75106
}
76107

77108
// Process returns the ProviderManager process

providers/providers_manager_test.go

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,10 @@ func TestProviderManager(t *testing.T) {
2626
defer cancel()
2727

2828
mid := peer.ID("testing")
29-
p := NewProviderManager(ctx, mid, dssync.MutexWrap(ds.NewMapDatastore()))
29+
p, err := NewProviderManager(ctx, mid, dssync.MutexWrap(ds.NewMapDatastore()))
30+
if err != nil {
31+
t.Fatal(err)
32+
}
3033
a := u.Hash([]byte("test"))
3134
p.AddProvider(ctx, a, peer.ID("testingprovider"))
3235

@@ -64,7 +67,10 @@ func TestProvidersDatastore(t *testing.T) {
6467
defer cancel()
6568

6669
mid := peer.ID("testing")
67-
p := NewProviderManager(ctx, mid, dssync.MutexWrap(ds.NewMapDatastore()))
70+
p, err := NewProviderManager(ctx, mid, dssync.MutexWrap(ds.NewMapDatastore()))
71+
if err != nil {
72+
t.Fatal(err)
73+
}
6874
defer p.proc.Close()
6975

7076
friend := peer.ID("friend")
@@ -144,7 +150,10 @@ func TestProvidesExpire(t *testing.T) {
144150

145151
ds := dssync.MutexWrap(ds.NewMapDatastore())
146152
mid := peer.ID("testing")
147-
p := NewProviderManager(ctx, mid, ds)
153+
p, err := NewProviderManager(ctx, mid, ds)
154+
if err != nil {
155+
t.Fatal(err)
156+
}
148157

149158
peers := []peer.ID{"a", "b"}
150159
var mhs []mh.Multihash
@@ -249,7 +258,10 @@ func TestLargeProvidersSet(t *testing.T) {
249258
}
250259

251260
mid := peer.ID("myself")
252-
p := NewProviderManager(ctx, mid, dstore)
261+
p, err := NewProviderManager(ctx, mid, dstore)
262+
if err != nil {
263+
t.Fatal(err)
264+
}
253265
defer p.proc.Close()
254266

255267
var mhs []mh.Multihash
@@ -281,7 +293,10 @@ func TestUponCacheMissProvidersAreReadFromDatastore(t *testing.T) {
281293
p1, p2 := peer.ID("a"), peer.ID("b")
282294
h1 := u.Hash([]byte("1"))
283295
h2 := u.Hash([]byte("2"))
284-
pm := NewProviderManager(ctx, p1, dssync.MutexWrap(ds.NewMapDatastore()))
296+
pm, err := NewProviderManager(ctx, p1, dssync.MutexWrap(ds.NewMapDatastore()))
297+
if err != nil {
298+
t.Fatal(err)
299+
}
285300

286301
// add provider
287302
pm.AddProvider(ctx, h1, p1)
@@ -302,7 +317,10 @@ func TestWriteUpdatesCache(t *testing.T) {
302317

303318
p1, p2 := peer.ID("a"), peer.ID("b")
304319
h1 := u.Hash([]byte("1"))
305-
pm := NewProviderManager(ctx, p1, dssync.MutexWrap(ds.NewMapDatastore()))
320+
pm, err := NewProviderManager(ctx, p1, dssync.MutexWrap(ds.NewMapDatastore()))
321+
if err != nil {
322+
t.Fatal(err)
323+
}
306324

307325
// add provider
308326
pm.AddProvider(ctx, h1, p1)

0 commit comments

Comments
 (0)