[Seaside] Seaside and Dynamic variables
David Shaffer
cdshaffer at acm.org
Thu Nov 17 05:28:55 CET 2005
Avi Bryant wrote:
>
> This stuff always makes my head hurt :)
Yes...mine too. My only consolation is that I've been able to guess my
way through most of it...
>
> I'm a little bit surprised that we stay in the same dynamic context
> even across a #call: with your method. Are you sure that you do?
> Can you explain why it works?
Sorry, right now I'm going on my gut and quick code browsing. I expect
that you know it much better than I do:
The first continuation that is captured always has the initial
start: in its context. I think this is unavoidable unless I missed an
escape because the first request sends start: to the session which
eventually captures the first continuation and records it
Subsequent request jumps into that stack, possibly capturing new
continuations but never returning up through the start: (the render loop
itself prevents that) unless there is an unhandled exception.
call: captures a continuation (which must have start: in the stack)
and adds an answer handler with it. Unless the AnswerHandler does
something very surprising then I expect that it simply evaluates this
continuation. I don't see anything escaping start: in this case.
I simply don't see how the app could function unless start: was on the
stack...still not much of an explanation.
I did have one problem with my original code. I forgot to send isolate:
CustomSession>>start: aRequest
Bindings clamp: [
Bindings isolate.
^super start: aRequest]
which caused some problems that I didn't see until today. With the
isolate, however, things seems to be working fine (famous last words).
>
> Generally, for the kind of thing you're describing I'd guess the most
> reliable (or at least simplest to understand) method would be to
> subclass WASession and add an ivar to store your variable. That
> might couple things too tightly to Seaside in some cases, however.
That's exactly the problem...can't be restricted to having a
(WA)session. I've come up with three alternative patterns:
1) Use the normal withEscapeContinuation: version (the first one I
listed) but store a ValueHolder in the dynamic variable. Then move the
actual value into MyDynamicVariable value contents: when it becomes
available
2) Use the session when it is available and a dynamic variable when
it is not. This can be hidden in the dynamic variable's value protocol
so it comes out pretty clean to use.
3) Mock up a session for use in non web code. This seems, well,
less that aesthetically pleasing but I have session-like things for
non-WA code in several places already.
I'm thinking about moving to 2 or 3...they avoid all of this messyness.
I was motivated to bring this to the group because I saw Cees using
dynamic variables in his Kilinea (SP?) package using the method which I
consider "wrong" but which certainly works for him (he creates the DB
session before he stores it in the dyn. var. the first time). I figure
others might be doing it as well.
David
More information about the Seaside
mailing list