[Twisted-web] Livepage, ClientHandle and context
Donovan Preston
dp at ulaluma.com
Wed Jun 1 20:25:42 MDT 2005
Thank you very much for your feedback. Please, anyone else on this
list who is using or attempting to use LivePage, let me know what you
are doing with it or plan on doing with it. I want to take it from
long-running experiment to solid, deployable code before the next
release, and need to know how much API stability/backwards
compatibility I should provide. I also need to know how people want
to use LivePage, and if it has any usability shortcomings with this
new design which I describe below. If there are any, I'd like to fix
them before the next release.
On Jun 1, 2005, at 4:46 PM, Alexey Shamrin wrote:
> On 5/31/05, Donovan Preston <dp at ulaluma.com> wrote:
>
>> In this branch, input handlers can also return javascript which will
>> be executed as the response to the input event.
>
> What do you mean? I don't understand...
> Are you talking about javascript that will be executed without
> round-trip to server?
When a client-side event generates a trip to the server over the
input conduit, the server-side handler method which is invoked can
now return javascript stan. This return result is written as the
response to the HTTP request which dispatched the event to the
server, and the browser evals it. Previously, the server would
arrange for the handler method to be called in the next reactor
iteration and close the input HTTP request, writing nothing to it.
The handler method would then call methods on the client handle which
would generate javascript and buffer it or write it directly to the
output conduit.
So yes, one (output conduit) round trip is eliminated, and it becomes
easier to support normal AJaX style events (where the browser is the
only thing initiating requests, and the server does no pushing),
which I call input only mode.
>> I encourage anyone who is interested in livepage to take a look at
>> this branch to see where it is going. Take a look at the examples to
>> see what has changed, read the code, and experiment with it. Ask
>> questions if you have any. I'll be trying to merge this branch into
>> the mainline (after adding some backwards compatibility) in the next
>> week.
>>
>> I'll also be adding some LivePage docs. I think the API will settle
>> down after this last round of changes.
>>
>
> 1. nevow_insertNode from liveglue.js (and livepage.insert) is broken.
> And (as far as I can see) it is not used anywhere in Nevow (including
> examples). Remove?
I think I might fix it rather than removing it. I'll also write a
test for it, since livetest can now reliably test livepage apps.
> 2. I think you should have "nevow_" prefix for all things in
> liveglue.js.
I agree, except I think I want the new "server" object to keep that
name. It will be much easier for people to understand and use
livepage if they know that calling server.handle('foo') in javascript
invokes the handle_foo method on the server. Are there other things
in there that aren't prefixed with nevow_?
> 3. What is the purpose of ClientHandle.transient?
ClientHandle.transient and LivePage.locateHandler (whose default
implementation looks for handle_* methods) are the new, easier to
understand and use replacements for the handler decorator.
Previously, there was a problem with handler because it registered
the callable you gave it in a dictionary which lived for as long as
the LivePage instance it was associated with. This means if you had a
really, really long lived LivePage (which LivePage is designed to
allow) you would leak more and more closures that the client can't
ever call again (because you replaced the client-side dom that
referenced those server-side closures with something else)
Now, if you provide a handle_foo method, the client can always call
server.handle('foo') as many times as it wants. However, it is still
useful to register closures on the server and give the client the
capability to call it. To avoid the aforementioned garbage problem,
transient allows you to do this, but only allows the client to call
it once, then pops the registration.
This avoids the garbage problem well; if the client closes the
browser, LivePage guarantees that the ClientHandle will die no more
than 90 seconds later, taking the transient closure registration
dictionary with it. If you are, for example, putting an "ok/cancel"
dialog on the user's screen, you can register a single transient
which gets called by either the ok or cancel button, ensuring that
the transient will be popped when the client no longer has the
capability to call it (because the UI has gone away, by the user
clicking either ok or cancel)
> 4. Are these two equivalent?
> onsubmit=livepage.server.handle(livepage.js.onSubmit, getValue
> ('inputline'))
> onsubmit=livepage.server.handle('onSubmit', getValue('inputline'))
No, because the client-side javascript "handle" function takes a
string. The first would render down to:
server.handle(onSubmit, getValue('inputline'))
The second would render down to:
server.handle('onSubmit', getValue('inputLine'))
The first would barf because the global name onSubmit doesn't exist.
The livepage.js object is like a stan.Tag for javascript; it creates
literal javascript. For example:
livepage.js.foo -> foo
livepage.js.foo('1') -> foo('1')
livepage.js('any string') -> any string
livepage.js['1'] -> ['1']
livepage.js.foo['1'] -> foo['1']
There are a bunch of other js objects in the module now, such as
window, document, this, server, set, append, alert, etc. They are
really convenient for making your python code much shorter.
I have an incredible LivePage app I wrote recently I am calling
"Pavel". I will be cleaning it up soon and I will create a new open
source project for it (rather than including it as a nevow example).
I think it really showcases the power of LivePage and I'm excited to
show it to people, but for now it is somewhat of a secret :-)
> P.S. At this time I have only read the code and checked new
> examples... I will try to experiment with it soon. But I must say your
> javascript "constructor" looks interesting (livepage.assign,
> livepage.var etc.)
assign and var are two experiments to get around the fact that python
has no assignment overloading. Here are examples of usage:
var(js.x, 5) -> var x = 5
assign(js.x, 10) -> x = 10
One other thing while I am discussing stan for javascript. This is a
pain once you start using it, but I don't think there is any way
around it other than education. You need to terminate your
statements, since the javascript flatteners have no idea where it is
appropriate to put newlines in javascript. So if you were sending the
following:
client.send([
livepage.alert('hello'),
livepage.set('name', 'Donovan Preston')])
You would need to terminate each statement, otherwise the javascript
won't be correct. The above example would render as:
alert('hello')set('name', 'Donovan Preston')
Right now, you need to do:
client.send([
livepage.alert('hello'), livepage.eol,
livepage.set('name', 'Donovan Preston')])
Which will render down to:
alert('hello')
set('name', 'Donovan Preston')
It occurs to me that it may be possible for Nevow to just infer that
a newline is required between each element of a list or a tuple while
in JavascriptContext. I will have to experiment and see whether this
causes any inadvertent problems. If not, the requirement to manually
insert newline characters will go away (horray!)
Donovan
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://twistedmatrix.com/pipermail/twisted-web/attachments/20050601/501e0bb3/attachment.htm
More information about the Twisted-web
mailing list