1. 19

  2. 11

    This is a very old idea and it has some merit (asides from being extremely cool technically speaking), but if you look critically at it there are several issues with it:

    • Deploying a new version of the code may make old sessions stale and completely invalid because they refer to code that doesn’t exist anymore.
    • Serializing a continuation requires an indeterminate amount of memory space (it takes care to ensure you don’t accidentally serialize too much state).
    • In general, I’ve learned the hard way (via lots of bad PHP programs) that saving too much state in the session totally breaks the back button, multi-tabbed browsing and so on.
    • If you work around the previous issue by not serializing it in the session but in the browser itself, it will become easier to inspect and manipulate the state.
    1. 2

      Though it doesn’t come off very clearly from the article, I argue for a mixed approach. Keep the session separate from continuations (via a session id cookie and some form of backend session storage), use stateless, restful URLs for the parts of the application that ought to be shareable (the vast majority of pages in an application) and only sprinkle continuations in places where you’re having to manipulate objects local to a page. I think this approach has its merits.

    2. 11

      Seaside was the first framework I saw that really delivered on this design well (though WebObjects notably came really close without actually using closures). Factor also has a continuation based web server that meshes well with plain REST, making it really easy to use the memory-heavy continuation model for admin and other lightly trafficked pages.

      1. 8

        My Factor articles PDF has a chapter on building continuation based HTTP responders from scratch. The text of that chapter is here. I used to use continuation based servers a lot in the past. It was one of the first things that interested me in Factor when I found out it had continuations.

        1. 2

          I remember Avi Bryant speaking about IOWA at RubyConf in 2002 (IOWA had just that year been to Smalltalk to become Seaside). We were wowed at the idea that you could write a web application in a linear, procedural style, rather than the discontinuous, event-driven style we were used to.

          I’m not sure where Avi got the idea to use call/cc for a web framework, but it was so intuitive, I’m convinced the Ruby web development world would look completely different today, if Ruby had had an efficient implementation of continuations at the time.

        2. 4

          There may be a better source, and I think there might actually be an expired patent owned by Yahoo!, but Paul Graham’s common lisp based startup (1990s) was built to take advantage of these ideas. He mentions it in these notes from 2001.

          1. 3

            Arc still uses these ideas. Until a couple of years ago you’d see people complaining on HN about clicking on a link and finding out it was expired.

            On a slightly pedantic note, while Paul Graham is talking about continuation passing style, he isn’t actually talking about using continuations. Just closures. This thread is useful context. It’s intended to be a tool for rapid prototyping, intended to be replaced with real links over time (as HN has since done).

            1. 2

              CPS still creates continuations. These may not be quite the same as those you get from Racket’s call/cc implementation, or its delimited continuations, but it still represents the rest of the computation, is stored in a first class way, and is resumable.

              Furthermore, this strategy can be used to implement control flow (as seen in arc, IcedCoffeeScript, and all the other implementations of CPS based control flow).

              For all intents and purposes the k parameter in CPS and “real” continuations (ironically, often implemented in toy schemes with CPS) are equal, but not equivalent.

          2. 3

            Continuations? Now there’s a name I haven’t heard for a long time… A long time.

            1. 10

              You’re clearly interacting with the wrong crowd ;) I’ve just been talking about them today (granted, I’m at a CHICKEN meetup, but still).

              1. 2

                Yeah I probably am.

            2. 3

              This is a very cool idea and I think the idea of incorporating security tokens improves on the suggestions given by Queinnec in section 7 of his paper.

              To combat this and to prevent servers’ memory usage from growing indefinitely, the web-server library has a robust implementation of an LRU continuation manager that expires continuations quicker the more memory pressure there is.

              Does this run the risk of expiring live sessions?

              1. 3

                Yes, it does, though you do get control over what happens when someone tries to execute a continuation that has been expired via the instance-expiration-handler. What I do when that happens is I redirect the user back to the calling page (stripping out the continuation parameter from the current URL) and add a flash message letting them know they should try again: https://github.com/Bogdanp/racket-webapp-template/blob/master/app-name-here/components/page/common.rkt#L21-L29 .

                Thank you for linking that paper, btw. I hadn’t seen it before.

              2. 2

                I’m (trying to) learn Elixir/Phoenix right now, and they have something called LiveView which looks sort of similar. People are doing really cool things with it, like a single page blackjack game that runs without JavaScript.

                1. 2

                  The idea was also explored in Continuity for Perl, which is only a couple years newer than Seaside, but it wasn’t used for anything serious that I know of. It makes a really cool toy, but the fact that state is local to a process is a pretty big handicap. You can’t load-balance without session sticking; you have to keep those continuation frames around for the session lifetime; and a server going away means a bunch of users have their session state dumped. It’s almost exactly the opposite of what I try to do in “real life”.

                  1. 2

                    I wrote a whole PHP framework based on this idea way back in 2004! It worked very poorly in practice: hard to explain, full of session serialization bugs, and much crummier performance than the equivalent emerging memcache + LAMP approach. Would not repeat.

                    1. 1

                      I’m impressed that was even possible on PHP as it existed in 2004. Unless I’m missing something, even PHP 7 doesn’t have continuations. How’d you implement this? Was it similar to something like Ruby’s IOWA (which did not use continuations, but provided a WebObjects-like development flow through WebObjects-like techniques of serializing a very heavy session store)?

                      1. 1

                        I modeled a virtual stack concept as a linked list of PHP objects, each of which represented a nested editing state for a database object. The continuation wasn’t in PHP4 itself, but in a half-baked DB-backed OOP stack sitting in front of it.

                        The funhouse mirror of Twisted Python a couple years later cured me of this insanity; much more into dumb-simple setups since emerging from this twisted maze of passages.