Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cache ipns entries to speed things up a little #1887

Merged
merged 1 commit into from
Nov 2, 2015
Merged

Conversation

whyrusleeping
Copy link
Member

This adds a quick minute long cache to ipns entry resolution.
Currently, ipns is pretty much unusable for webpages as each sub-request must re-resolve the entry.

License: MIT
Signed-off-by: Jeromy [email protected]

@jbenet jbenet added the status/in-progress In progress label Oct 22, 2015
@ion1
Copy link

ion1 commented Oct 22, 2015

It would be good to reflect that in a Cache-Control max-age header for /ipns addresses on the gateway.

https://github.com/ipfs/go-ipfs/issues/1818

@kyledrake
Copy link

👍

@whyrusleeping
Copy link
Member Author

After this merges i encourage people to really start using ipns, and reporting any issues to me. I'm pretty confident in it (post this changeset), but thats not to say it won't have any issues.

@ion1
Copy link

ion1 commented Oct 25, 2015

I did an experiment with the current master, publishing a new object every few seconds and polling the IPNS address on the public gateway. It seemed to work impressively quickly at times while being slow to publish and resolve at other times.

I have been thinking of doing an experiment with live video streaming in this way. Unfortunately, this change might affect the current update rate negatively.

On the other hand, if I were to publish a blog using IPNS, I might be fine with nodes having a stale version of the record for up to an hour.

I realize future pubsub support will cover the live streaming use case, but having the ability to do ipfs name publish --ttl=5s for the streaming experiment and ipfs name publish --ttl=1h for the blog example would let the publisher make the choice between low latency and greater caching (in this example, choosing to have a cache time an order of magnitude greater than the one minute).

Don’t let this delay merging this PR, but I hope IPNS records will gain a TTL field (like in DNS records) in the future.

return 0, err
}

ct := cfg.Ipns.ResolveCacheTime
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we have this in the default config too?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we can, but we dont need to. It assumes that an empty value means the default value of one minute.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i thought for the sake of documentation ;)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added to the default config

@whyrusleeping whyrusleeping added RFCR and removed status/in-progress In progress labels Oct 27, 2015
eol, ok := checkEOL(entry)
if ok && eol.Before(cacheTil) {
cacheTil = eol
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this stuff could get easily wrong, and cache time errors could behavior drastically. i'd propose feeding entry into r.cacheSet and put the computation in one place, calculated always from the original data, instead of intermediate values.

@jbenet
Copy link
Member

jbenet commented Oct 28, 2015

i'd support the addition of the --ttl flag for name publish, as a means to experiment for now (mark it experimental)

@jbenet
Copy link
Member

jbenet commented Oct 28, 2015

👍 to this PR in general.

@whyrusleeping
Copy link
Member Author

@ion1 @jbenet i have a --nocache option that will ignore the cached value when requesting a record. I will also add the --ttl, but wiring that down is a little more intrusive.

@whyrusleeping
Copy link
Member Author

er, wait. that option is already there in the form of --lifetime

@whyrusleeping whyrusleeping force-pushed the feat/ipns-cache branch 2 times, most recently from 1bc21f0 to 5db2437 Compare October 28, 2015 04:30
@whyrusleeping
Copy link
Member Author

@jbenet do you want --lifetime renamed to --ttl? or are we good to merge?

@jbenet
Copy link
Member

jbenet commented Oct 28, 2015

@jbenet do you want --lifetime renamed to --ttl? or are we good to merge?

ah, no, good to merge. not merge yet, actually

@jbenet
Copy link
Member

jbenet commented Oct 28, 2015

no, dont merge yet. still CRing

cacheTil := time.Now().Add(r.cachelife)
eol, ok := checkEOL(rec)
if ok && eol.Before(cacheTil) {
cacheTil = eol
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

um... this isn't used anywhere.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is an interesting case of go's unused variable error. Its used, then assigned to, then that assigned value is never used.

@ghost
Copy link

ghost commented Oct 28, 2015

I'm a bit worried this will hide speed problems enough that they don't get fixed...
Also, it makes the "IPNS livestream" idea kind of problematic, since you'll have a minute long delay on new updates thanks to the cache.

@whyrusleeping
Copy link
Member Author

@gamemanj read the comment chain.

@whyrusleeping
Copy link
Member Author

@jbenet actually used that variable.

@ion1
Copy link

ion1 commented Oct 28, 2015

publish --lifetime=48hours --ttl=1hour would be perfectly sensible:

  • The record is considered invalid 48 hours after the publish time.
  • You don’t need to ask the network for possible updates to the record for 1 hour after having received a copy, i.e. I’m okay with others keeping a stale version of my record for up to 1 hour.

The Cache-Control/max-age header is determined by --ttl (the semantics match perfectly), not --lifetime.

This adds a quick minute long cache to ipns entry resolution.

This is the time --ttl would control.

“No cache” should be a property of the record (i.e. --ttl=5s when you are livestreaming for example).

@whyrusleeping
Copy link
Member Author

@ion1 @gamemanj I also want to point out that live streaming will be done best by pubsub, ipns polling for streaming is equatable to setting your dns records to each frame of the video, one at a time. Not to say that you shouldnt try it, and that ipns should be slow, but thats just not its intended purpose.

@whyrusleeping
Copy link
Member Author

changed the value back to 16, and changed the cache to an lru, with a configurable size.

No other DHT parameters changed here, weird things started happening when i tweaked K, so i'm not going to bother until later.

@ion1
Copy link

ion1 commented Nov 1, 2015

Nice. Is the cache lifetime limit useful in addition to the LRU policy though? How about letting popular records with long TTLs be cached as long as their TTL value allows?

You could get the TTL value from the record, fall back to a default of one minute, compute time.Now().Add(ttl), limit that according to the record EOL and use that as the cache expiry for that record. I could then return the cache entry’s expiry.Sub(time.Now()) as the current TTL in #1921.

@ion1
Copy link

ion1 commented Nov 1, 2015

Also, the LRU cache implementation does its own locking.

return
}

ctx = context.WithValue(ctx, "ipns-publish-ttl", d)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 we should enhance the context much more often.

This would allow us to get a trace of where it failed in timeouts instead of a blank "deadline exceeded".

@ion1
Copy link

ion1 commented Nov 1, 2015

@whyrusleeping, please see my commits in https://github.com/ion1/go-ipfs/commits/feat/ipns-cache

The first commit has some fixes for things including the redundant locking and lru.New failing given a zero size.

The second commit removes cachelife with the assumption that the LRU policy along with respecting the TTL (and EOL) fields is enough.

@cryptix
Copy link
Contributor

cryptix commented Nov 1, 2015

@whyrusleeping I also fixed your tests.. :) Qmduc5TqSk5hWnuvBCDHQMXnPALPZ131Jz9wbU9SYTbjyB

ion1 added a commit to ion1/go-ipfs that referenced this pull request Nov 1, 2015
License: MIT
Signed-off-by: Johan Kiviniemi <[email protected]>
@whyrusleeping whyrusleeping force-pushed the feat/ipns-cache branch 2 times, most recently from 1bd03c0 to 9957772 Compare November 1, 2015 22:06
@cryptix cryptix mentioned this pull request Nov 2, 2015
47 tasks
@whyrusleeping
Copy link
Member Author

@jbenet this is RFM i beleive. @ion1 @cryptix can i get some thumbs ups?

@cryptix
Copy link
Contributor

cryptix commented Nov 2, 2015

👍 used it already

@ion1
Copy link

ion1 commented Nov 2, 2015

ion1@f531ad3

I refactored the EOL computation out of cacheSet. I’m going to need its result for the Cache-Control PR, it would be a bit hairy to pull the value out of cacheSet.

@ion1
Copy link

ion1 commented Nov 2, 2015

ion1@bd84894

A bit better: return both the absolute eol and the relative ttl and use ttl > 0 to decide whether the result should be cached. This will also make it nicer for the Cache-Control PR.

@ion1
Copy link

ion1 commented Nov 2, 2015

<whyrusleeping> ion: okay. Just go ahead and apply that in your PR once 1887 merges

Alright.

👍, especially after squashing so one commit doesn’t add cachelife just for another to remove it.

@jbenet
Copy link
Member

jbenet commented Nov 2, 2015

this LGTM

jbenet added a commit that referenced this pull request Nov 2, 2015
cache ipns entries to speed things up a little
@jbenet jbenet merged commit d673275 into master Nov 2, 2015
@jbenet jbenet deleted the feat/ipns-cache branch November 2, 2015 23:11
@jbenet
Copy link
Member

jbenet commented Nov 2, 2015

@whyrusleeping @ion1 @cryptix damn i merged this without realizing-- there's no tests. can we write some?

@whyrusleeping
Copy link
Member Author

@jbenet sure thing! #1934

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants