parameter *widget-action-symbiosis* (default t):
"Whether to assume that references to actions (e.g. links) are
rendered within the dynamic context of the call to
`render-widget-body' that renders the widget directly containing
said references.
Essentially, when this is NIL, `kill-action-with-render' does
nothing. We strongly recommend doing all rendering for any given
widget within the dynamic context of the `render-widget-body' call
on that particular widget. If this does not describe your code, you
may want to set me to NIL."
function kill-action-with-render:
"When WIDGET is not nil (by default the currently-rendering widget,
aka the innermost `render-widget' call), arrange for ACTION-CODE's
deletion when the browser is no longer rendering it.
We try to be conservative with this, so ACTION-CODE will not be
deleted immediately on the following request, but instead on the
request that follows that, to avoid the race between the browser
rendering cycle and impatient multi-clicking users. Deletion may also
occur when the widget is garbage-collected."
This seems incredibly straightforward given the render-widget-body
methods I write, and the style that we have advocated repeatedly with
regard to separating action handling and rendering on this list, but I
wanted to see if styles in the wild broke these assumptions. Otherwise,
I'll throw trivial-garbage onto the fire (see the end of that last
docstring there) and push it today or tomorrow.
Full patch attached:
If the page comes from your browser's cache: the action is executed again
because the action id hasn't changed.
If the page is fresh: a new action closure is generated and invoked.
No, it's never being deleted from the action hash table as long
as the table exists (i.e. for the duration of the session).
If that action link is part of a widget that has since been rerendered,
you'll get an error as if the action didn't exist. If it is a widget
that was just undisplayed, the link would work. Browsers with
Javascript will mostly experience the latter because they can't use Back
to undo an Ajax rerender. None of this applies to clicking Back once,
because we keep actions for a single cycle.
I don't think this is a problem because apps are not in general
guaranteed to work even in minorly untrivial cases with the back button.
Imagine deleting an item of a gridedit, clicking back, and trying to
drill into it. Furthermore, imagine an action linked to a widget that
is no longer part of the tree.
"Leslie P. Polzer" <sky-A/mCt7huS1RhCjiJD...@public.gmane.org> writes:
> No, it's never being deleted from the action hash table as long
> as the table exists (i.e. for the duration of the session).
This deletion is just what this patch does.
--
Sorry but you say Nibiru is a Hoax? Doesnt Exist? So maybe The
Sumerian people doesnt exist also! --Anonymous by way of SkI
I would disable this feature by default, and have programmers who know
they want this enable it explicitly.
I suppose, but I don't think this patch helps with that. It's a
slightly harder problem, because of impatience. Including the
double-clickers.
> I suppose setting up actions outside of widget rendering will
> just result in these actions not being GC'd?
Anyway you shouldn't call render-link and render-form outside of widget
rendering. Calling `make-action' does not do the association, but an
action may only associate with one widget. I think that rendering
actions without one of the `render-*' functions or their macro wrappers
should yield undefined behavior.
I hijacked `log-ui-action', a debugging function that is always called
anyway, for this.
> I reviewed the patch; it looks good although the terminology is
> a bit florid. From what planet did you snatch it?
Trill. Essentially "symbiosis": the action cannot live without its
widget.
> Got some tests, too?
Ha, no. But what it does isn't nailed down yet, I guess.
Vyacheslav Akhmechet <coffeemug-Re5JQE...@public.gmane.org> writes:
> You really don't like the back button, do you? :)
Me too, and I also hate "friendly" URLs. They encourage needless
minimalism in user interface design, which is great for request-response
protocols but crappy for context-sensitive humans. I believe that
they'll have to be mostly abandoned for the UI of web applications in
general to improve. But there's a whole essay there.
> Personally, I'm a bit wary of the idea, but it would be interesting to
> see if it adds any frustration in practice. I would make this an
> option that's turned off by default.
I would rather add a little complexity to make it more acceptable and
have it on by default. There's little sense in an implementation detail
most users have to think about to use, if ever at all.
We can't prevent people from digging into "opaque" structures, or
reimplementing render-link for their own code in a potentially
incompatible or may-be-incompatible-in-future way. We can only say that
doing so isn't supported.
>> I hijacked `log-ui-action', a debugging function that is always called
>> anyway, for this.
>
> For what exactly? I can't associate the 'this' at the end...
The patch.
>> Trill. Essentially "symbiosis": the action cannot live without its
>> widget.
>
> Now I could've thought of that...
Trill, or symbiosis? ;)
>> Me too, and I also hate "friendly" URLs. They encourage needless
>> minimalism in user interface design,
>
> What's the relation between friendly URLs and UI minimalism?
> I'm curious.
Consider the classic-model equivalent of a datagrid with drilldown. In
most cases, the ideal interface is for the search results to remain on
screen, with the appropriate filter and pagination parameters
remembered, while the detailed view appears along with the search
datagrid on the same page.
However, this is not friendly-URL-compatible. The gold standard for a
friendly URL here is to only record the result item type and ID. For
example, a Trac ticket is reached via /ticket/<ticket#>. Recording
search information makes the URL less friendly, because query-strings
are bad for Googleness. So there is a conflict between
user-friendliness and Google-friendliness.
I'm not against people providing selectors that accept friendly or
permanent URLs (e.g. the "Link" link on Google Maps). I'm against the
practices of the Internet forcing web developers to cater to search
engines rather than users.
>> I would rather add a little complexity to make it more acceptable and
>> have it on by default.
>
> +1.
I'm just not sure what that complexity should be. We can't determine
when an action would no longer work, for example. We could keep entries
for more cycles, but `cycle-widget-symbiotic-actions' would grow in time
and space with the cycle count.
When we know that an opportunity to mess with opaque structures/protocols
is attractive then we should strive to detect the user messing about in
there.
>>> Trill. Essentially "symbiosis": the action cannot live without its
>>> widget.
>>
>> Now I could've thought of that...
>
> Trill, or symbiosis? ;)
The former one. :)
> However, this is not friendly-URL-compatible. The gold standard for a
> friendly URL here is to only record the result item type and ID. For
> example, a Trac ticket is reached via /ticket/<ticket#>. Recording
> search information makes the URL less friendly, because query-strings
> are bad for Googleness.
Are they? I'm not so sure of that. IME Google will handle query strings
just fine.
> So there is a conflict betweenuser-friendliness and Google-friendliness.
For me friendly in the context of URLs just means that I can bookmark
and copy them easily to others.
> I'm not against people providing selectors that accept friendly or
> permanent URLs (e.g. the "Link" link on Google Maps). I'm against the
> practices of the Internet forcing web developers to cater to search
> engines rather than users.
Considering our different original interpretations we're on the same
page now.
>>> I would rather add a little complexity to make it more acceptable and
>>> have it on by default.
>>
>> +1.
>
> I'm just not sure what that complexity should be. We can't determine
> when an action would no longer work, for example.
Still not sure where it might happen that a dead URL is invoked;
the only case I can think of is having multiple views of a page/widget;
but in this case we're fully desynchronized anyway (that's another
problem domain).
Actually, Slava pinpointed the case where you would see a dead URL—in
certain situations when using the Back button, more commonly when
Javascript is disabled. So if we don't care about the back button,
which I argued for earlier in this thread, the patch is fine as-is (+
patch tests trivial-garbage).
Yes, and I still don't see the point -- action URLs should be fresh
even when the back button is used.
I just see it as a pretty big UI annoyance in exchange for very little
benefit. When a session times out, everything can be picked up by the
garbage collector anyway, so what is this for? Very long sessions? I
just don't see what pain the patch solves. Normally this wouldn't
bother me, but I feel like making the back button behavior even worse
is a pretty major issue.
You're missing my point. One of our basic axioms is that dynamic pages
should come fresh from the server and must not be cached on the client.
And another limitation that we have regardless of whether we have an
action GC or not is that multiple views into the same widget tree (mostly
isomorphous with URL) are not working that well.
So I still don't get how the action GC changes anything here.
> And another limitation that we have regardless of whether we have an
> action GC or not is that multiple views into the same widget tree (mostly
> isomorphous with URL) are not working that well.
That's true, but in case of back buttons users expect some kind of
support, they're happy with something that doesn't work all the time
but kind of works some of the time. By garbage collecting the actions,
you're breaking that expectation, and I think it's pretty important.
It might be worth doing if you get something significant, but I don't
see any significant benefits.
The users *will* click on the back button and *will* click on old
actions. Currenly, if enough state is still around (which is usually
the case), the actions will do the right thing. If the state isn't
around (which happens occassionally), the actions will do something
semi-reasonable. By semi-reasonable, I mean something that doesn't
freak people out too much.
Actually, I think I understand now what you mean. The fact that AJAX
isn't kept in the history? Then yes, whenever there is AJAX request
for a given URI (other than the first AJAX request for that URI), we
can safely garbage collect the actions of the the previous request
because the page has no chance of being cached in the browser. I was
mostly concerned about non-AJAX requests, which are a big part of most
applications. Does this clear up what I meant?
Imagine a calendar widget in month or year view, using Weblocks render
instead of Javascript, with an action link for each day, and month/year
setting actions.
Alternatively, imagine that we arrange for Javascript ping to keep
sessions open as long as the browser is open to the webapp. (Recently I
did a search in one webapp, browsed several pages of results, left it
alone in a tab for a couple days, and came back to it.) Hell, the ping
could pick up mysteriously dirty widgets.
Alteralternatively, I may simply be obsessive about these things. This
patch is pretty much a reenactment of
http://groups.google.com/group/gnu.emacs.bug/msg/fe139186a6332e3d
Got one of those, but it's not in full production yet so
I can't say anything about the real-world impact.
> Alternatively, imagine that we arrange for Javascript ping to keep
> sessions open as long as the browser is open to the webapp. (Recently I
> did a search in one webapp, browsed several pages of results, left it
> alone in a tab for a couple days, and came back to it.) Hell, the ping
> could pick up mysteriously dirty widgets.
I have such an app too and believe it doesn't really matter much.
But it's not up to full scale yet either so that need not signify
anything.
Anyway, I definitely think that this is useful functionality,
so perhaps we should introduce it right away but turn it off by
default until we agree otherwise.
> Alteralternatively, I may simply be obsessive about these things. This
> patch is pretty much a reenactment of
> http://groups.google.com/group/gnu.emacs.bug/msg/fe139186a6332e3d
Well. I think there are areas of work that would be a better spending
of your time, but we're a volunteer project after all. ;)
Leslie