From e37166168b755d3c498206ba39a84b91bfc86997 Mon Sep 17 00:00:00 2001 From: Jeromy Date: Sat, 24 Oct 2015 00:11:01 -0700 Subject: [PATCH] make cache time configurable License: MIT Signed-off-by: Jeromy --- core/commands/ipns.go | 2 +- core/core.go | 31 ++++++++++++++++++++++++++++-- namesys/namesys.go | 6 ++++-- namesys/republisher/repub_test.go | 3 ++- namesys/resolve_test.go | 6 +++--- namesys/routing.go | 12 ++++++------ repo/config/ipns.go | 2 ++ test/sharness/t0240-republisher.sh | 1 + 8 files changed, 48 insertions(+), 15 deletions(-) diff --git a/core/commands/ipns.go b/core/commands/ipns.go index 54afa20396c..eb4bc9ed66d 100644 --- a/core/commands/ipns.go +++ b/core/commands/ipns.go @@ -66,7 +66,7 @@ Resolve the value of another name: resolver = n.Namesys if local, _, _ := req.Option("local").Bool(); local { offroute := offline.NewOfflineRouter(n.Repo.Datastore(), n.PrivateKey) - resolver = namesys.NewRoutingResolver(offroute) + resolver = namesys.NewRoutingResolver(offroute, 0) } var name string diff --git a/core/core.go b/core/core.go index d62465ea945..6040812b561 100644 --- a/core/core.go +++ b/core/core.go @@ -226,8 +226,13 @@ func (n *IpfsNode) startOnlineServicesWithHost(ctx context.Context, host p2phost bitswapNetwork := bsnet.NewFromIpfsHost(n.PeerHost, n.Routing) n.Exchange = bitswap.New(ctx, n.Identity, bitswapNetwork, n.Blockstore, alwaysSendToPeer) + cachelife, err := n.getCacheLifetime() + if err != nil { + return err + } + // setup name system - n.Namesys = namesys.NewNameSystem(n.Routing, n.Repo.Datastore()) + n.Namesys = namesys.NewNameSystem(n.Routing, n.Repo.Datastore(), cachelife) // setup ipns republishing err = n.setupIpnsRepublisher() @@ -238,6 +243,23 @@ func (n *IpfsNode) startOnlineServicesWithHost(ctx context.Context, host p2phost return nil } +func (n *IpfsNode) getCacheLifetime() (time.Duration, error) { + cfg, err := n.Repo.Config() + if err != nil { + return 0, err + } + + ct := cfg.Ipns.ResolveCacheTime + if ct == "" { + return namesys.DefaultResolverCacheLife, nil + } + d, err := time.ParseDuration(ct) + if err != nil { + return 0, fmt.Errorf("error parsing cache life from Ipns.ResolveCacheTime: %s", err) + } + return d, nil +} + func (n *IpfsNode) setupIpnsRepublisher() error { cfg, err := n.Repo.Config() if err != nil { @@ -456,7 +478,12 @@ func (n *IpfsNode) SetupOfflineRouting() error { n.Routing = offroute.NewOfflineRouter(n.Repo.Datastore(), n.PrivateKey) - n.Namesys = namesys.NewNameSystem(n.Routing, n.Repo.Datastore()) + cachelife, err := n.getCacheLifetime() + if err != nil { + return err + } + + n.Namesys = namesys.NewNameSystem(n.Routing, n.Repo.Datastore(), cachelife) return nil } diff --git a/namesys/namesys.go b/namesys/namesys.go index b6b7cd9f73b..17815f1f360 100644 --- a/namesys/namesys.go +++ b/namesys/namesys.go @@ -26,12 +26,12 @@ type mpns struct { } // NewNameSystem will construct the IPFS naming system based on Routing -func NewNameSystem(r routing.IpfsRouting, ds ds.Datastore) NameSystem { +func NewNameSystem(r routing.IpfsRouting, ds ds.Datastore, cachelife time.Duration) NameSystem { return &mpns{ resolvers: map[string]resolver{ "dns": newDNSResolver(), "proquint": new(ProquintResolver), - "dht": NewRoutingResolver(r), + "dht": NewRoutingResolver(r, cachelife), }, publishers: map[string]Publisher{ "/ipns/": NewRoutingPublisher(r, ds), @@ -39,6 +39,8 @@ func NewNameSystem(r routing.IpfsRouting, ds ds.Datastore) NameSystem { } } +const DefaultResolverCacheLife = time.Minute + // Resolve implements Resolver. func (ns *mpns) Resolve(ctx context.Context, name string) (path.Path, error) { return ns.ResolveN(ctx, name, DefaultDepthLimit) diff --git a/namesys/republisher/repub_test.go b/namesys/republisher/repub_test.go index e050c3c6193..92c224a738e 100644 --- a/namesys/republisher/repub_test.go +++ b/namesys/republisher/repub_test.go @@ -19,7 +19,6 @@ import ( func TestRepublish(t *testing.T) { // set cache life to zero for testing low-period repubs - namesys.IpnsCacheLife = 0 ctx, cancel := context.WithCancel(context.Background()) defer cancel() @@ -37,6 +36,8 @@ func TestRepublish(t *testing.T) { t.Fatal(err) } + nd.Namesys = namesys.NewNameSystem(nd.Routing, nd.Repo.Datastore(), 0) + nodes = append(nodes, nd) } diff --git a/namesys/resolve_test.go b/namesys/resolve_test.go index 4d81751f1b5..11145ff0198 100644 --- a/namesys/resolve_test.go +++ b/namesys/resolve_test.go @@ -19,7 +19,7 @@ func TestRoutingResolve(t *testing.T) { d := mockrouting.NewServer().Client(testutil.RandIdentityOrFatal(t)) dstore := ds.NewMapDatastore() - resolver := NewRoutingResolver(d) + resolver := NewRoutingResolver(d, 0) publisher := NewRoutingPublisher(d, dstore) privk, pubk, err := testutil.RandTestKeyPair(512) @@ -53,7 +53,7 @@ func TestPrexistingExpiredRecord(t *testing.T) { dstore := ds.NewMapDatastore() d := mockrouting.NewServer().ClientWithDatastore(context.Background(), testutil.RandIdentityOrFatal(t), dstore) - resolver := NewRoutingResolver(d) + resolver := NewRoutingResolver(d, 0) publisher := NewRoutingPublisher(d, dstore) privk, pubk, err := testutil.RandTestKeyPair(512) @@ -90,7 +90,7 @@ func TestPrexistingRecord(t *testing.T) { dstore := ds.NewMapDatastore() d := mockrouting.NewServer().ClientWithDatastore(context.Background(), testutil.RandIdentityOrFatal(t), dstore) - resolver := NewRoutingResolver(d) + resolver := NewRoutingResolver(d, 0) publisher := NewRoutingPublisher(d, dstore) privk, pubk, err := testutil.RandTestKeyPair(512) diff --git a/namesys/routing.go b/namesys/routing.go index 52c2c5c2cec..99f806dcb68 100644 --- a/namesys/routing.go +++ b/namesys/routing.go @@ -24,13 +24,14 @@ type routingResolver struct { cache map[string]cacheEntry cachelock sync.Mutex + cachelife time.Duration } func (r *routingResolver) cacheGet(name string) (path.Path, bool) { r.cachelock.Lock() entry, ok := r.cache[name] r.cachelock.Unlock() - if ok && time.Now().Sub(entry.recvd) < IpnsCacheLife { + if ok && time.Now().Sub(entry.recvd) < r.cachelife { return entry.val, true } @@ -46,8 +47,6 @@ func (r *routingResolver) cacheSet(name string, val path.Path) { r.cachelock.Unlock() } -var IpnsCacheLife = time.Minute - type cacheEntry struct { val path.Path recvd time.Time @@ -55,14 +54,15 @@ type cacheEntry struct { // NewRoutingResolver constructs a name resolver using the IPFS Routing system // to implement SFS-like naming on top. -func NewRoutingResolver(route routing.IpfsRouting) *routingResolver { +func NewRoutingResolver(route routing.IpfsRouting, cachelife time.Duration) *routingResolver { if route == nil { panic("attempt to create resolver with nil routing system") } return &routingResolver{ - routing: route, - cache: make(map[string]cacheEntry), + routing: route, + cache: make(map[string]cacheEntry), + cachelife: cachelife, } } diff --git a/repo/config/ipns.go b/repo/config/ipns.go index feab6f044f7..2dcbbea1623 100644 --- a/repo/config/ipns.go +++ b/repo/config/ipns.go @@ -3,4 +3,6 @@ package config type Ipns struct { RepublishPeriod string RecordLifetime string + + ResolveCacheTime string } diff --git a/test/sharness/t0240-republisher.sh b/test/sharness/t0240-republisher.sh index bb643d17ec5..c005f957c45 100755 --- a/test/sharness/t0240-republisher.sh +++ b/test/sharness/t0240-republisher.sh @@ -26,6 +26,7 @@ setup_iptb() { for i in $(test_seq 0 3) do ipfsi $i config Ipns.RepublishPeriod 20s + ipfsi $i config Ipns.ResolveCacheTime 0s done '