- Arc doesn't cause the expired link issue. Arc is just a Lisp that lets
- you write your program however you want. The HN software is written in
- a style that uses closures to remember what a user is up to across
- multiple web requests. I'll describe a classic example of this, then
- how we changed it and why.
- When you click "More" at the bottom of a page, HN shows you the next
- 30 stories. These are different for logged-in users--they're affected
- by profile settings like "showdead"--so, if you're logged in, the
- system needs to compute the next 30 stories to show you. Which 30
- those are depends on the ones you were just looking at. So the server
- needs to know what you were just looking at in order to handle the
- "More" request correctly. How does it know that? There are many ways.
- HN's traditional way is to make a closure (a function that remembers
- any info it needs) at the time that it's generating the original page,
- which, if and when it is called, will compute the correct next 30
- The advantage of doing it this way is that, at the time you're making
- that closure, all the information you need to process the next request
- correctly is already right there in scope. You don't have to remember
- it, reconstitute it, or anything--all of which takes extra code, and
- different code for each kind of request.
- You can't send the closure directly to the web browser, so you make a
- unique ID instead, save that closure in a table keyed by the ID, and
- put the ID in a link. When the user clicks that link, the server gets
- the ID, looks up the closure, and executes it.
- If you're saving lots of closures, eventually you'll run out of RAM if
- you don't garbage-collect some. So the HN server periodically prunes
- the oldest ones. If one of those links is still open in a browser
- window somewhere and the user clicks on it, the server will no longer
- remember what to do. That is when HN says "expired link".
- As HN grew larger, there were many more of these closures, and the
- odds were higher that someone would try to use one after it was
- pruned. A few months ago, since we were working on that part of the
- code anyway, we decided to eliminate the most common cases. We
- measured all the different kinds of closure in the table and replaced
- the most common ones with more traditional ways of passing state back
- to the server, like query strings and hidden form fields. We did that
- until the total number of closures was down by an order of magnitude,
- and then--equally importantly--we stopped. Now the system has enough
- RAM to remember the vast majority of closures again, and the "expired
- link" errors have gone down to a tiny fraction of what they were
- before. (The one unfortunate exception to this is when we restart the
- server process.)
- I was the person who changed the code to not use closures for "More"
- links and other common cases, and it gave me a new appreciation for
- how powerful the closure technique is. Getting rid of those closures
- was a pain, and it made the code more complicated. When HN was first
- being built, the tradeoff in favor of programming ease was a
- no-brainer. In fact, it's because of methods like this that HN exists
- at all, because HN wouldn't exist if one person (pg) hadn't been able
- to build it in his spare time. The fact that it lasted as a one-man
- side project for something like 7 years is evidence of how powerful
- its software design is. The closure technique is one piece of that,
- and it's still used throughout the codebase. It would be foolish to
- try to replace all of them; the same tradeoff in favor of programming
- efficiency is still the dominant factor in most of those cases because
- they are relatively little used.
a guest Oct 7th, 2014 938 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
RAW Paste Data