continuations

Being Opaque

March 17, 2004 16:20:43.414

In a comment on my earlier post on Seaside URLs, Vincent D Murphy writes

...I still have a reservation with what you say about using a session key. Why not use the HTTP headers for session keys? I still think that opaque string has no place in a URI.
If we're actually talking about session keys, this is true: it could be stored in a cookie instead of the URL. I happen to dislike this approach in general because it means you can't have two concurrent sessions with the same application from the same browser, but I can see the arguments on the other side as well, and if someone submitted a patch to Seaside that allowed you to configure an application either way, I would probably accept it.

However, there are actually two opaque IDs in a Seaside URL: as well as a session key, there's also a continuation key, and that's the interesting one that we can't do without. Why does it have to be opaque? Because the resource that it is a locator for is a suspended computation: specifically, it's a serialized copy of the actual stack frames of the application process as they were when that particular URL was generated. Try as you might, you're not going to come up with a short, meaningful representation of that; the only thing you can do is assign it a unique ID and stick it in a table somewhere. Why does it have to be in the URL? For any one session you have hundreds of them - one per page view - and if you're allowing backtracking or multiple browser windows then many of them can be active at once. For any given request, you need to know exactly which page view it came from so that you can resume the session from the right point. Cookies can't do that for you.

But the opaqueness isn't really what bothers people, or shouldn't be. Seems to me like pretty much every web app since the first database-backed CGIs has had URLs with "meaningless" primary keys stuck in them somewhere; how else are you supposed to refer to one particular object or record out of thousands like it? The difference is that in Seaside, the object being referred to is a transient one: you don't expect to keep a given continuation around forever (although you could, if you had enough disk space), whereas a key into a Customer table will probably be valid for quite a while. So this, I believe, is the crux of the matter: is it ok for URLs to refer to transient, short lived resources? To get rid of the obvious objection, let's assume these URLs are still useful even once the transient resource is gone, they're just more useful when it's still around.

For me, the answer is obvious. When an application is running, it generates thousands and thousands of transient objects: objects modelling the current state of the user interface (is that portal channel collapsed or maximized? What are the last seven things the user entered into that search field?) , the current point in a workflow (exactly which path did the user follow to get to this page?), the temporary state of an uncommitted transaction, and on, and on, in endless combinations. These aren't interesting resources in the greater scope of "the web" - you would never want to link to them from an external site. But they are extremely interesting in the context of the current session, and to forbid yourself from directly referencing them is to put on a straitjacket that I have absolutely no interest in wearing. Continuations are, to me, a particularly interesting example of such resources, but the idea of using opaque URLs to reference transient session objects (rather than the session as a whole) goes back at least as far as NeXT and WebObjects, if not further.

Comments

hidden input?

[Gordon Weakliem] March 17, 2004 17:50:30.264

How about putting the continuation in a form element? True, this works only for pages with forms, but it seems like those are where continuations provide the benefit. If you're just doing simple browsing (clicking URLs), do continuations help for that case? That said, I'm not particularly against having opaque bits in the URL, as long as they pass the cut & paste tests 1. Cut & Paste actually works. 2. Session hijacking can be prevented where necessary (i.e. shopping carts, a user's credit card page).

re: hidden input?

[Chad Fowler] March 17, 2004 18:36:42.698

On the question of whether continuations are simple if you're just clicking URLs, for a trivial example, you could look at the demo apps that ship with Seaside. Even the counter application demonstrates how "simple clicking" can be meaningful interaction in a web application. Think about applications like Amazon or eBay. Lots of simple clicking going on, with lots of state being kept. How different are these URL clicks from the single-click actions that you do in the rest of your desktop environment? I would say that clicking a folder in my email client or the "save" button on my text editor isn't much different than clicking a URL. HREFs are just another widget, really. That being said, there's no reason you couldn't work up some kind of hack to use hidden form variables *even using links*. You would probably have to use some ugly JavaScript and inappropriate use of hidden forms, but it's possible. At a certain point you have to ask yourself, "Why am I bothering?" I think this one wouldn't pass the laziness test for me. :)

re: hidden input?

[Avi Bryant] March 17, 2004 18:45:45.153

It's not really about hidden inputs vs. URLs, it's about GET vs POST - yes, if you use POST everywhere, the user doesn't see as much in the location bar of the URL, and you get the nice property that if you bookmark or copy and paste you only get the permanent part. On the other hand, I find POSTs really annoying, because browsers tend to prompt you a lot about them ("resubmit form data?"). Seaside actually does a redirect after every POST to avoid this (and to generally avoid double-submit problems). This makes Seaside apps very reload happy.

If anyone has any brilliant suggestions for how to get the best of both worlds, I'm all ears.

Literate Urls v.s. Ugly Urls

[Peter William Lount] March 17, 2004 22:48:08.038

Very illuminating Avi. Please see my questions, observations and suggestions at http://smallblog.smalltalk.org:9999/seaside/blog/SmalltalkDotOrg.

Re: Literate URLs

[Avi Bryant] March 17, 2004 23:41:18.770

Peter,

The answer to most of your comments is this: the way it is now leads to the cleanest and most natural implementation. I have tried both modifications you suggest (collapsing the two IDs into one, using URL params instead of hiearchical segments), and although I agree it's an improvement in the location bar it's a net loss in the code. I'll look again at the URL param change, since a few different people have suggested it, even though it muddies the semantics of the framework internals somewhat (I seriously doubt anyone but me would care). There will probably be two separate IDs for the foreseeable future, however - among other things, it makes session-affinity load balancing possible (with a proxy that knows which sessions are handled by which instance).

As for putting continuation IDs in cookies, no way. I'm not going to present the user with a "preference" that amounts to "do you want to horribly cripple the usability of this application for no real gain?" If you want to hack that in for your apps, go ahead.

Literate Urls v.s. Ugly Urls, response 2

[Peter William Lount] March 18, 2004 5:15:49.800

GET vs. POST

[Colin Putney] March 18, 2004 11:24:15.965

The other problem with using POST all over the place is that it's an abuse of the HTTP specification. According to the spec, the meaning of POST is that submitting the form will have some effect on the real world: your blog entry will be visible to the world, your credit card will be charged and goods will be shipped to you, some politician will be credited with your vote, whatever. That's why browsers are careful about resubmitting POST requests, as they should be - reloading that page might have side-effects the user doesn't want. (As a side note, what annoys me about the way most browsers behave is not that they're wary about resubmitting POSTs, but that they refuse to show me stale pages. When I backtrack, it's because I want to see what I saw before, not because I want to do again what I did before.) One thing I like about the way Seaside handles state is that it actually makes sense according to the semantics of HTTP. When you submit a form or click on a link, the meaning of the server's response is something like "Ok, your request has been processed and the results are available at this URL." Now you can do whatever you like with that URL, because viewing the results is a different action than creating them. In this sense, Seaside URLs are actually more meaningful than those found in most dynamic web sites. IMNSHO, the "usual" way of writing web apps is a hack that takes advantage of the way browsers behave but ignores the intended semantics of the web. Yeah, it works, mostly, but the fact that it's so mind-numbing to actually do is an indication that something, somewhere, has gone terribly wrong.

2 reasons not to use cookies

[Ian "Learning Seaside" Prince ] March 18, 2004 12:39:31.694

Here are 2 reasons not use cookies: (1) cookie handling in my experience is poorly implemented and documented in browsers, for example cookies are not stored if you have a Windows-like hostname such as "http://MYSERVER/" (2) you can't write curl-style client programs, I don't see any way to "add" a continuation cookie to "curl http://blogs.inextenso.com/seaside/blog/learning/'

Re: Being Opaque

[James Robertson] March 18, 2004 13:33:37.253

Comment on Being Opaque by James Robertson

Don't forget to add this problem with cookies:

End users can disable them

To Cookie or Not To Cookie?

[Peter WIlliam Lount] March 18, 2004 14:59:11.962

Please see http://smallblog.smalltalk.org:9999/seaside/blog/SmalltalkDotOrg/9e437f76-854f-4626-a234-dcae5f1130f0 for my comments on the reasons stated against cookies in the above couple of comments.

Continuation IDs InURLs Are Requred

[Peter William Lount] March 18, 2004 16:10:15.986

I stand corrected about the necessity of a "continuation id" in URLs in the way that Avi has implemented Seaside. After reviewing what Avi's is saying I now have a better understanding of what Avi is doing with continutation IDs in the links on a web page. This continuation stuff is as clear as mud on the first few dozen passes. Avi is correct in that Cookies can't be used for them. Please see: http://smallblog.smalltalk.org:9999/seaside/blog/SmalltalkDotOrg/b9f41438-4982-4b79-b40a-fe14920d1d45.

Comments

[Avi Bryant] March 18, 2004 17:14:59.367

Peter: sorry it was confusing, but glad you've figured out what I meant. I think we see eye to eye now - one could use cookies for sessions, or not, and the continuation id could/should go into a param, but it has to be there.

Colin: I agree with you 99%, but can't pat myself on the back too much: Seaside does abuse HTTP in that it often has links (which are necessarily GET requests) with side effects. However, having one request with side effects that's immediately redirected to another without, even if the first was a GET, stays pretty close to the spirit of HTTP, if not to the letter (and if there were a way to have something that looked and acted like a link but used POST, I'd use it). Incidentally I've seen this referred to elsewhere as the "PRG" pattern (post-redirect-get) so Seaside clearly isn't the only system out there that uses it.

Untitled

[Chris Double] March 18, 2004 18:15:31.488

One downside of using parameters for the continuation id is that web search engines may not index the page. Don't they tend to ignore dynamic GET/POST requests?

Robots

[Avi Bryant] March 18, 2004 18:58:20.698

Chris, search engines are a whole other can of worms. Cees and I came up with some decent ways of automatically building a view of a Seaside site tailored to search engines (I know they hate it when you do that, but it's for their own good). His implementation is called Janus, and he uses it for tric.nl. If url params stop them from following links in the normal, non-SEO view, that's probably for the best.

Port 9999 not accessible to all

[Rowan Bunning] March 18, 2004 21:45:30.303

The Software WithStyle team was enjoying reading these comments until they started being made available via port 9999 which is blocked by the firewall we are behind. Might it be possible to refrain from using non-standard ports that aren't accessible to all? Thanks.

Port 9999

[Peter William Lount] March 18, 2004 22:40:27.761

Sorry about that port 9999 ick, it's certainly not condusive to friendly URLs or Literate URLs for that matter. Blush. It's a temporary solution until we have our main blog up and running. It sounds like you are behind a very restrictive firewall. Try opening up the port on your firewall for external access.