diff --git a/core/commands/publish.go b/core/commands/publish.go index 0737a011721..0e539868db2 100644 --- a/core/commands/publish.go +++ b/core/commands/publish.go @@ -52,6 +52,7 @@ Publish an to another public key (not implemented): Options: []cmds.Option{ cmds.BoolOption("resolve", "resolve given path before publishing (default=true)"), cmds.StringOption("lifetime", "t", "time duration that the record will be valid for (default: 24hrs)"), + cmds.StringOption("ttl", "time duration this record should be cached for (caution: experimental)"), }, Run: func(req cmds.Request, res cmds.Response) { log.Debug("Begin Publish") @@ -96,7 +97,18 @@ Publish an to another public key (not implemented): popts.pubValidTime = d } - output, err := publish(req.Context(), n, n.PrivateKey, path.Path(pstr), popts) + ctx := req.Context() + if ttl, found, _ := req.Option("ttl").String(); found { + d, err := time.ParseDuration(ttl) + if err != nil { + res.SetError(err, cmds.ErrNormal) + return + } + + ctx = context.WithValue(ctx, "ipns-publish-ttl", d) + } + + output, err := publish(ctx, n, n.PrivateKey, path.Path(pstr), popts) if err != nil { res.SetError(err, cmds.ErrNormal) return diff --git a/namesys/pb/namesys.pb.go b/namesys/pb/namesys.pb.go index 4d99a5e0a20..0508e772dfd 100644 --- a/namesys/pb/namesys.pb.go +++ b/namesys/pb/namesys.pb.go @@ -57,6 +57,7 @@ type IpnsEntry struct { ValidityType *IpnsEntry_ValidityType `protobuf:"varint,3,opt,name=validityType,enum=namesys.pb.IpnsEntry_ValidityType" json:"validityType,omitempty"` Validity []byte `protobuf:"bytes,4,opt,name=validity" json:"validity,omitempty"` Sequence *uint64 `protobuf:"varint,5,opt,name=sequence" json:"sequence,omitempty"` + Ttl *uint64 `protobuf:"varint,6,opt,name=ttl" json:"ttl,omitempty"` XXX_unrecognized []byte `json:"-"` } @@ -99,6 +100,13 @@ func (m *IpnsEntry) GetSequence() uint64 { return 0 } +func (m *IpnsEntry) GetTtl() uint64 { + if m != nil && m.Ttl != nil { + return *m.Ttl + } + return 0 +} + func init() { proto.RegisterEnum("namesys.pb.IpnsEntry_ValidityType", IpnsEntry_ValidityType_name, IpnsEntry_ValidityType_value) } diff --git a/namesys/pb/namesys.proto b/namesys/pb/namesys.proto index 242f77bf2ab..d6eaf3243fe 100644 --- a/namesys/pb/namesys.proto +++ b/namesys/pb/namesys.proto @@ -12,4 +12,6 @@ message IpnsEntry { optional bytes validity = 4; optional uint64 sequence = 5; + + optional uint64 ttl = 6; } diff --git a/namesys/publisher.go b/namesys/publisher.go index e31217dff33..78d7bb37cc9 100644 --- a/namesys/publisher.go +++ b/namesys/publisher.go @@ -121,6 +121,19 @@ func (p *ipnsPublisher) getPreviousSeqNo(ctx context.Context, ipnskey key.Key) ( return e.GetSequence(), nil } +// setting the TTL on published records is an experimental feature. +// as such, i'm using the context to wire it through to avoid changing too +// much code along the way. +func checkCtxTTL(ctx context.Context) (time.Duration, bool) { + v := ctx.Value("ipns-publish-ttl") + if v == nil { + return 0, false + } + + d, ok := v.(time.Duration) + return d, ok +} + func PutRecordToRouting(ctx context.Context, k ci.PrivKey, value path.Path, seqnum uint64, eol time.Time, r routing.IpfsRouting, id peer.ID) error { namekey, ipnskey := IpnsKeysForID(id) entry, err := CreateRoutingEntryData(k, value, seqnum, eol) @@ -128,6 +141,11 @@ func PutRecordToRouting(ctx context.Context, k ci.PrivKey, value path.Path, seqn return err } + ttl, ok := checkCtxTTL(ctx) + if ok { + entry.Ttl = proto.Uint64(uint64(ttl.Nanoseconds())) + } + err = PublishEntry(ctx, r, ipnskey, entry) if err != nil { return err diff --git a/namesys/routing.go b/namesys/routing.go index 123b5fbd7c1..aebac546c12 100644 --- a/namesys/routing.go +++ b/namesys/routing.go @@ -40,7 +40,16 @@ func (r *routingResolver) cacheGet(name string) (path.Path, bool) { } func (r *routingResolver) cacheSet(name string, val path.Path, rec *pb.IpnsEntry) { - cacheTil := time.Now().Add(r.cachelife) + ttl := r.cachelife + if rec.Ttl != nil { + // if the record has a ttl set, and its less than ours, use it instead + recttl := time.Duration(rec.GetTtl()) + if recttl < ttl { + ttl = recttl + } + } + + cacheTil := time.Now().Add(ttl) eol, ok := checkEOL(rec) if ok && eol.Before(cacheTil) { cacheTil = eol