How to make synchronous calls without synchronous calls

28 views
Skip to first unread message

Ryan Stewart

unread,
May 28, 2008, 2:49:34 PM5/28/08
to Google Web Toolkit
Greetings. I've witnessed the antipathy toward synchronous calls
around here, so I'm not here to ask how to make a synchronous call.
I'm asking for advice on how to do something that I can only think how
to do using a synchronous call.

I want to implement ORM-like lazy loading in GWT, meaning, in a
nutshell, that objects sent from the server to the browser will have
the ability, on a method call, to call back to the server to retrieve
data. For example, var bar = foo.getBar() would involve a call to the
server to retrieve the Bar. This is synchronous by nature, as when the
method returns, you expect that "bar" is populated and you can use it
in further code.

Can anyone suggest a way, other than a synchronous call, to do this
that 1) is _non-intrusive_ to using code and 2) would not be
considered a hack?

By 1), I mean that the line "var bar = foo.getBar()" needs to stay
exactly like it is--no monkeying around with async callbacks and
timeouts and such unless it can be hidden away somewhere behind the
scenes.

quentin

unread,
May 28, 2008, 3:52:10 PM5/28/08
to Google Web Toolkit
Why not use the callback? Otherwise your only option, really, is to
set a "bar" instance on foo before serializing it to the client so
that the getBar() method call doesnt need to go back to the server.

Ryan Stewart

unread,
May 28, 2008, 3:58:49 PM5/28/08
to Google Web Toolkit
On May 28, 2:52 pm, quentin <qcomps...@gmail.com> wrote:
> Why not use the callback?
Because it's asynchronous, which won't work as I described in my
original post.

> Otherwise your only option, really, is to
> set a "bar" instance on foo before serializing it to the client so
> that the getBar() method call doesnt need to go back to the server.
The need to do this is exactly what I'm attempting to prevent.

quentin

unread,
May 28, 2008, 4:26:11 PM5/28/08
to Google Web Toolkit
Hm, tough one. What do you need to do with the results of the call to
getBar()? Are you sure its not possible to relocate this logic to a
callback?

gregor

unread,
May 28, 2008, 4:36:47 PM5/28/08
to Google Web Toolkit
Hi Ryan,

You cannot do what you are suggesting because, unlike a Java RMI call
for example, javascript code will not sit waiting for foo.getBar() to
execute an RPC call and field the response. It will fire off (and
forget) the request and then continue on to the return statement of
the function, in this case returning null. This is the reason for the
callback mechanism (to pick up the response and pass it to a new
method for action i.e. onSuccess()) and it is necessary to design
client code with this in mind. It's how javascript works, you can't
get round it.

regards
gregor

Thomas Broyer

unread,
May 28, 2008, 7:11:46 PM5/28/08
to Google Web Toolkit

On May 28, 10:36 pm, gregor <greg.power...@googlemail.com> wrote:
>
> You cannot do what you are suggesting because, unlike a Java RMI call
> for example, javascript code will not sit waiting for foo.getBar() to
> execute an RPC call and field the response. It will fire off (and
> forget) the request and then continue on to the return statement of
> the function, in this case returning null.

Not true: XMLHttpRequest can be made synchronous but it's not
recommended for evident usability reasons, so GWT enforces asynchrous
requests.

(every presentation about "ajax apps performance" or "ajax apps
usability" will tell you that: embrace asynchronousness)

...so if you really don't care about usability and your users, you can
still use JSNI to make a synchronous XMLHttpRequest...

Ryan Stewart

unread,
May 28, 2008, 11:54:25 PM5/28/08
to Google Web Toolkit
On May 28, 3:26 pm, quentin <qcomps...@gmail.com> wrote:
> Hm, tough one. What do you need to do with the results of the call to
> getBar()?
There's no set answer to this. It's a generic solution.

> Are you sure its not possible to relocate this logic to a
> callback?
Yes. Callback = asynchronous. Asynchronous = broken code in this
instance.

Ryan Stewart

unread,
May 29, 2008, 12:26:40 AM5/29/08
to Google Web Toolkit
On May 28, 6:11 pm, Thomas Broyer <t.bro...@gmail.com> wrote:
[...]
> ...so if you really don't care about usability and your users, you can
> still use JSNI to make a synchronous XMLHttpRequest...

I've worked up the JSNI version already. I was just hoping for a
better solution. This leads me to another question about serializing
objects on the client, which I've posted here:
<http://groups.google.com/group/Google-Web-Toolkit/browse_thread/
thread/ee10d56ba84f334b>

"Synchronous calls = bad user experience" is simply incorrect. Blanket
statements like this are dangerous. Personally, I feel that GWT's
exclusion of synchronous XMLHttpRequests simply because it can cause
problems with certain browsers in certain situations is a mistake. It
means there are some situations in which GWT could provide even fuller
functionality but doesn't. It should be the responsibility of the
developer to decide whether synchronous requests are appropriate for a
given situation.

In my particular situation, the application being constructed will be
used by a small group of people--far less than 50 at any time--who all
work on a LAN where the tightest bottleneck is the 100Mb NICs. The
speed of the network and servers being used combined with the way the
application is already being developed and used mean that any issues
caused by using properly managed synchronous calls will likely go
unnoticed by the users.

Does this allay your concern for my users?

Reinier Zwitserloot

unread,
May 29, 2008, 2:06:33 AM5/29/08
to Google Web Toolkit
This is yet another rant on why GWT will not be adding synchronous
calls. However, there's one piece of useful advice in there if you can
dig your way through the vitriol. However, you have to understand that
your particular situation (small group, fat pipes, in a single office)
is not something GWT normally caters for. There's not currently any
way to plaster 'holy #$*@#($*# don't use this unless all users are a
stone's throw from the server!' into a programmer's editor, so the
alternative is even worse.


On May 29, 6:26 am, Ryan Stewart <zzant...@gmail.com> wrote:
> "Synchronous calls = bad user experience" is simply incorrect.

You don't get it. In the time it takes for your ORMy thingie to query
your server, THE BROWSER HANGS. Okay, fine, for you that time is so
short people won't notice. That doesn't change this fact.

In javascript, 'synchronous calls = bad user experience' is simply
correct.

You want to FAKE a synchronous call perhaps. In theory you could cook
something up, but GWT can't do it, and it won't anytime soon; there's
too much low-level hackery to be done to make that sort of thing work.

> It should be the responsibility of the
> developer to decide whether synchronous requests are appropriate for a
> given situation.

GWT is open source. Make a tiny patch to gwt-user.jar if you really
really want to make your users throw bricks through your window. It's
not hard at all; GWT's code is quite nicely written. I've actually
done this to my GWT; a few patches which fortunately have all been
accepted for GWT 1.5.

Ryan Stewart

unread,
May 29, 2008, 8:28:57 AM5/29/08
to Google Web Toolkit


On May 29, 1:06 am, Reinier Zwitserloot <reini...@gmail.com> wrote:
[...]
> You don't get it.
Yes, I get it.

> In the time it takes for your ORMy thingie to query
> your server, THE BROWSER HANGS. Okay, fine, for you that time is so
> short people won't notice. That doesn't change this fact.
It doesn't change the fact, but it makes it acceptable.

> In javascript, 'synchronous calls = bad user experience' is simply
> correct.
...in *most* cases, emphasis on "most". You agreed above that in my
specific case, this is false. Yet, in spite of the "most," javascript
provides this functionality. I simply find it odd that GWT enforces
this artificial constraint on developers.

> You want to FAKE a synchronous call perhaps. In theory you could cook
> something up, but GWT can't do it, and it won't anytime soon; there's
> too much low-level hackery to be done to make that sort of thing work.
What sort of low-level hackery? Do you have something specific in
mind? This is the sort of thing I'm looking for with this post,
whether through GWT or outside of it.

Yegor

unread,
May 29, 2008, 12:26:51 PM5/29/08
to Google Web Toolkit
There is another issue with allowing out-of-the-box synchronous RPC.
Many people are coming to GWT with regular Java experience, like
myself. They are used to doing synchronous RPC (RMI, etc). Sometimes
they know however that long-running tasks should run in threads
outside of the UI rendering thread. Even then I have seen many desktop
Swing applications that froze on every server call because people are
not following guidelines. Since in the browser you only have one
thread availability of synchronous calls will encourage bad design. So
to satisfy your extremely rare use-case (which, BTW, can perfectly be
worked out asynchronously) GWT would end up with unusable
applications. That would definitely kill the interest in the toolkit
which is judged by the quality of the applications created with it.

I am very glad that it is so hard to do what you are trying to do.

Yegor

Ryan Stewart

unread,
May 29, 2008, 12:53:23 PM5/29/08
to Google Web Toolkit
On May 29, 11:26 am, Yegor <Yegor.Jba...@gmail.com> wrote:
[...]
> So
> to satisfy your extremely rare use-case (which, BTW, can perfectly be
> worked out asynchronously) GWT would end up with unusable
> applications.
[...]
> I am very glad that it is so hard to do what you are trying to do.

Actually what I did is quite easy. I'm not trying to get into a debate
here. I'm just looking for information. I stated very clearly in my
original post that I wasn't asking about making a synchronous call.
I'm asking for advice on how best to solve a problem. It just happens
to be a problem that is very neatly solved by synchronous calls. Do
you mind explaining your "perfectly working asynchronous solution"?

gregor

unread,
May 29, 2008, 2:41:33 PM5/29/08
to Google Web Toolkit
Hi Ryan,

Well since Thomas has so comprehensively corrected me, it seems that
if you want to, you can easily call your server synchronously using a
JSNI method + a XMLHttpRequest. You merely have to code these calls
for all properties on each of your domain classes. Why are you raising
this on the forum since it looks like you already knew this in the
first place?

regards
gregor
Message has been deleted

Ryan Stewart

unread,
May 29, 2008, 4:44:04 PM5/29/08
to Google Web Toolkit
On May 29, 1:41 pm, gregor <greg.power...@googlemail.com> wrote:
> Hi Ryan,
>
> Well since Thomas has so comprehensively corrected me, it seems that
> if you want to, you can easily call your server synchronously using a
> JSNI method + a XMLHttpRequest. You merely have to code these calls
> for all properties on each of your domain classes. Why are you raising
> this on the forum since it looks like you already knew this in the
> first place?
>
> regards
> gregor
>
Because I regard both JSNI and synchronous requests as undesirable. I
came here to see if anyone had any thoughts on the best solution to
this problem. As I've not really received any concrete answers on this
front, I'm beginning to suspect that what I already have may be the
only, and therefore best, solution.

In addition, if I use JSNI to make a synchronous request, I don't get
the benefit of GWT's serialization unless I can figure out how to tie
into it manually. As I mentioned before, I've already posted another
question on that issue here:
http://groups.google.com/group/Google-Web-Toolkit/browse_frm/thread/ee10d56ba84f334b

From the lack of activity there, it seems that nobody has a good
answer for that, either.

Peter Blazejewicz

unread,
May 29, 2008, 5:03:28 PM5/29/08
to Google Web Toolkit
hi,

I think you have not defined your problem at all, instead you've
posted just glimpse of description of what you're actually trying to
implement. Java is strict, very formal language available for more
then 10 years around and it already took some existing solutions
(being solution for problems itself) for existing problems,
http://www.cmcrossroads.com/bradapp/javapats.html#Proxy
At first look it looks like you want Proxy patter to be implemented on
client. but only on first look. Have we seen "user" term or similiar
mentioned in description of problem somewhere? What is user role in
that problem? How "tab-bar" is related to user interaction? IT Mill
GWT implementation is based on concept: send barebone data to browser
first, then fill it with other content generated on server (but end-
user won't notice that),
http://www.itmill.com/

regards,
peter
> question on that issue here:http://groups.google.com/group/Google-Web-Toolkit/browse_frm/thread/e...

pohl

unread,
May 29, 2008, 5:36:01 PM5/29/08
to Google Web Toolkit


On May 29, 11:53 am, Ryan Stewart <zzant...@gmail.com> wrote:
>
> I stated very clearly in my original post that I wasn't asking about
> making a synchronous call. I'm asking for advice on how best to
> solve a problem.

I think that a synchronous call was implied by the way that you
described
the problem, unfortunately. At least that's the way I understand
this
passage:

> For example, var bar = foo.getBar() would involve a call to the
> server to retrieve the Bar. This is synchronous by nature, as when the
> method returns, you expect that "bar" is populated and you can use it
> in further code.

My understanding is that you would like the flow of the code to block
here: in particular, you want the function call on the right to block
until
it gets a value from the server. Only at that point would you like
the
assignment to happen, and only after the assignment happens should
the next line of code be executed. To me, this is not only
"synchronous
by nature", as you said, but "synchronous by definition".

I suspect you already agree on that point.

You've posed a fun problem, though: can one build a synchronous
mechanism
on top of an asynchronous — hopefully in a generic way that can be
hidden
behind the getBar() accessor — using the current asynchronous RPC as
the building blocks. Is that a fair restatement of the problem?

If so, the only thing that comes to mind is a method that invokes the
RPC and
then busy-waits until the response comes back, at which time the busy-
wait
Timer could be cancelled, and the method can return.

But I suspect that the harder problem would be to make it generic so
that
you could hide it behind the accessors of the entities in your ORM
framework.
Since GWT is very static by nature, you wouldn't be able to use
reflection.
Perhaps you could do something using the "generators" facility? I'm
not
sure, though — I haven't played with that much, yet.

Forgive me if I've further complicated the thread here.

Ryan Stewart

unread,
May 29, 2008, 11:34:09 PM5/29/08
to Google Web Toolkit
Peter Blazejewicz wrote:
> hi,
>
> I think you have not defined your problem at all, instead you've
> posted just glimpse of description of what you're actually trying to
> implement.
I'm not sure I quite follow you. I was pretty specific about what I'm
trying to do if you're familiar with the problem domain I mentioned
(lazy loading with ORMs).

> Java is strict, very formal language available for more
> then 10 years around and it already took some existing solutions
> (being solution for problems itself) for existing problems,
> http://www.cmcrossroads.com/bradapp/javapats.html#Proxy
> At first look it looks like you want Proxy patter to be implemented on
> client. but only on first look.
Yes, Proxy pretty well covers what I'm trying to do. In fact, I have a
class called ProxiedList to implement lazy loading for lists. (I'm
really most concerned about proxying out collections rather than
simple single-entity references.)

> Have we seen "user" term or similiar
> mentioned in description of problem somewhere? What is user role in
> that problem?
I'm not quite sure what you're asking about "user". If you mean end
user of the application, it has little or no meaning to them unless it
impacts their experience. My target "users" for this are developers.
It's intended to make development simpler by extending Hibernate's
lazy loading to the client, leaving us free to not care about pre-
initializing the right data for each use case.

> How "tab-bar" is related to user interaction?
Say what?

> IT Mill
> GWT implementation is based on concept: send barebone data to browser
> first, then fill it with other content generated on server (but end-
> user won't notice that),
> http://www.itmill.com/
I'm not sure if this is supposed to help me in what I'm looking for.
At a glance, it looks like something similar to GWT or Echo2 with
perhaps a bit more of it written for you.

Ryan Stewart

unread,
May 29, 2008, 11:41:46 PM5/29/08
to Google Web Toolkit
On May 29, 4:36 pm, pohl <pohl.longs...@gmail.com> wrote:
> I think that a synchronous call was implied by the way that you
> described
> the problem, unfortunately.
[...]
> My understanding is that you would like the flow of the code to block
> here:  in particular, you want the function call on the right to block
> until
> it gets a value from the server.  Only at that point would you like
> the
> assignment to happen, and only after the assignment happens should
> the next line of code be executed.   To me, this is not only
> "synchronous
> by nature", as you said, but "synchronous by definition".
Yes, that's correct. Maybe I shouldn't have mentioned "synchronous" at
all, but you've got right to the heart of the issue.

> You've posed a fun problem, though:  can one build a synchronous
> mechanism
> on top of an asynchronous — hopefully in a generic way that can be
> hidden
> behind the getBar() accessor — using the current asynchronous RPC as
> the building blocks.    Is that a fair restatement of the problem?
Again, you have it exactly right, yes.

> If so, the only thing that comes to mind is a method that invokes the
> RPC and
> then busy-waits until the response comes back, at which time the busy-
> wait
> Timer could be cancelled, and the method can return.
Yes, that's all I could think of, too.

> But I suspect that the harder problem would be to make it generic so
> that
> you could hide it behind the accessors of the entities in your ORM
> framework.
> Since GWT is very static by nature, you wouldn't be able to use
> reflection.
> Perhaps you could do something using the "generators" facility?  I'm
> not
> sure, though — I haven't played with that much, yet.
Well, in fact, I'm much more interested in applying this to x-to-many
relationships, where it's relatively simple to hide the magic in some
kind of collection proxy object. Getting it into the single-entity
accessors would just be icing on the cake. These "generators" you
speak of sound interesting. I'm unfamiliar with the term.

> Forgive me if I've further complicated the thread here.
Not at all. You seem to understand my problem perfectly, you've given
me possibly useful information, and you've confirmed that I'm thinking
along the right lines. Thanks very much for the reply.

jhulford

unread,
May 30, 2008, 10:15:19 AM5/30/08
to Google Web Toolkit
Perhaps you might want to include why you think you need the lazy
loaded collections - although I do think it's an interesting problem.
It seems to me that lazy loading a collection through RPC calls is
going to greatly impact your user experience - pauses between every
non-loaded access to the collection. If it were me I'd rather take
the initial hit and download the full collection of data to the
client. Either in 1 shot or through an IncrementalCommand type
approach that repeatedly queries the server for the next batch of data
until you have it all.

Ryan Stewart

unread,
May 30, 2008, 1:26:15 PM5/30/08
to Google Web Toolkit
On May 30, 9:15 am, jhulford <jhulf...@gmail.com> wrote:
> Perhaps you might want to include why you think you need the lazy
> loaded collections - although I do think it's an interesting problem.
Why do you need lazy loaded collections on the server side? Pretty
much any reason you can give applies since GWT moves the object graph
to the client. A big one is that lazy loading potentially keeps an
application's entire dataset from being loaded into memory when a
single object is loaded. Without this convenience, a developer either
has to let a much larger dataset than needed be loaded or has to
manually tune the loading for each use case. GWT breaks lazy loading
and thus forces the developer back into this situation.

> It seems to me that lazy loading a collection through RPC calls is
> going to greatly impact your user experience - pauses between every
> non-loaded access to the collection.
I'm not sure we're on quite the same page. In my model, when a
collection is accessed, the entire collection is initialized, so it
only involves a RPC on the first access. This will certainly entail a
pause of some sort, but that's hardly uncommon in a rich webapp. Think
of a tree with thousands of leaves at different levels. The generally
accepted way to deal with it is to load each branch on demand,
particularly when users will only be interested in a small subset of
the data in the tree at any time. A pause isn't a big issue as long as
it's in a spot that a user expects. Of course, if the only option is
to do this with a synchronous request, that might not be so great.

> If it were me I'd rather take
> the initial hit and download the full collection of data to the
> client.  Either in 1 shot or through an IncrementalCommand type
> approach that repeatedly queries the server for the next batch of data
> until you have it all.
Even if you had a tree of, say, 10 branches, each of which has 1000
leaves under it, and the user will need to look at only one branch at
a time in 99% of the use cases?

Lazy loading is just an integral part of enterprise applications. If
it weren't for the fact that it looks like it will have to be
synchronous to be ported to the client, I think that it could also be
a very popular feature for GWT.

walden

unread,
May 30, 2008, 3:22:23 PM5/30/08
to Google Web Toolkit


On May 30, 1:26 pm, Ryan Stewart <zzant...@gmail.com> wrote:
> On May 30, 9:15 am, jhulford <jhulf...@gmail.com> wrote:> Perhaps you might want to include why you think you need the lazy
> > loaded collections - although I do think it's an interesting problem.
>
> Why do you need lazy loaded collections on the server side? Pretty
> much any reason you can give applies since GWT moves the object graph
> to the client. A big one is that lazy loading potentially keeps an
> application's entire dataset from being loaded into memory when a
> single object is loaded. Without this convenience, a developer either
> has to let a much larger dataset than needed be loaded or has to
> manually tune the loading for each use case. GWT breaks lazy loading
> and thus forces the developer back into this situation.
>

It's important to apply "pay as you go" to data transfer design,
whenever there is a lot of data and/or a lot of network. This is
fairly obvious. However, Lazy/Eager loading goes beyond that by
trying to abstract away the load operation itself. Although elegant
in theory, I've found it to be a disappointment in practice, mainly
because the policy is specified per collection instead of per use
case. Then, dealing with the magic beans outside their sphere of
magic (PersistenceSet, e.g., in a detached instance) just adds to the
fun.

[What used to be known as] MyGWT has/d something called a
RemoteContentProvider which could be used with TreeTables and the
like. The entire framework supports the async model, so it satisfies
the requirement for "pay as you go", although it does not depend on
Lazy Loading to do this.

Bottom line, I'd say that Lazy Loading for detached entities is a
*nice to have*... maybe not all that nice, and certainly not
essential.

Walden

David Given

unread,
May 30, 2008, 7:59:36 PM5/30/08
to Google-We...@googlegroups.com
pohl wrote:
[...]

> Perhaps you could do something using the "generators" facility? I'm
> not
> sure, though — I haven't played with that much, yet.

No, you can't.

What you need to make this work are coroutines, which you can think of
as manually scheduled threads: they're fantastically useful for
simplifying the flow of code where the way you want to *write* the code
doesn't necessarily match the way the computer wants to *run* the code.
Languages like Lua have this.

Generators are a very stripped down form of coroutines that only allow
yielding and resuming across a single stack level. Unfortunately, this
isn't sufficient for anything other than the most trivial things, such
as iterators.

It's a shame that the ECMAScript committee decided not to implement full
coroutines in the new Javascript standard --- they are mindbogglingly
powerful things, and would allow, for example, basic GWT thread support,
as well as proper synchronous RPC like the OP wanted (as well as the
basic iterator support they wanted with generators). Unfortunately they
decided not to specify them because they thought requiring coroutine
support would complicate the VM too much...

--
┌─── dg@cowlark.com ───── http://www.cowlark.com ─────
│ "I have always wished for my computer to be as easy to use as my
│ telephone; my wish has come true because I can no longer figure out
│ how to use my telephone." --- Bjarne Stroustrup

signature.asc

Ryan Stewart

unread,
Jun 2, 2008, 10:55:45 AM6/2/08
to Google Web Toolkit
On May 30, 2:22 pm, walden <wmath...@aladdincapital.com> wrote:
> It's important to apply "pay as you go" to data transfer design,
> whenever there is a lot of data and/or a lot of network. This is
> fairly obvious. However, Lazy/Eager loading goes beyond that by
> trying to abstract away the load operation itself. Although elegant
> in theory, I've found it to be a disappointment in practice, mainly
> because the policy is specified per collection instead of per use
> case. Then, dealing with the magic beans outside their sphere of
> magic (PersistenceSet, e.g., in a detached instance) just adds to the
> fun.
True, lazy loading introduces its own set of interesting things to
deal with, such as how to port it to a rich JavaScript client :) This
is not a debate over the utility of lazy loading. Developers use lazy
loading to overcome certain problems. Developers also use GWT to
overcome other problems. It stands to reason that there is going to be
overlap between the two pools of developers and thus a gap that needs
to be filled between lazy loading on the server and GWT client code.

> [What used to be known as] MyGWT has/d something called a
> RemoteContentProvider which could be used with TreeTables and the
> like. The entire framework supports the async model, so it satisfies
> the requirement for "pay as you go", although it does not depend on
> Lazy Loading to do this.
Actually, what you're describing is lazy loading by definition, though
I understand that you mean it doesn't depend on ORM lazy loading. I've
seen this MyGWT widget, but my tree example was just a common example
where lazy loading is used in rich clients. What I'm attempting will,
if successful, have a much broader applicability than to lazy loading
tree structures.

[...]

Ping

unread,
Jun 3, 2008, 9:37:30 AM6/3/08
to Google Web Toolkit
One of the problems is a impedance mismatch between what you expect
when calling a get() and how most rich ui works (they work
asynchronously). If you can design an app expecting accessors
(getters) to be asynchronous and do some sort of event pub/sub for
class properties around it, you can implement something like lazy
loading for gwt. Not sure if is usefull, I think the best way is to
specifiy all data in the query beforehand: it saves you roundtrips to
db and it makes you think of how to design you application.

Ryan Stewart

unread,
Jun 3, 2008, 10:42:38 AM6/3/08
to Google Web Toolkit
On Jun 3, 8:37 am, Ping <miguel.p...@gmail.com> wrote:
> One of the problems is a impedance mismatch between what you expect
> when calling a get() and how most rich ui works (they work
> asynchronously). If you can design an app expecting accessors
> (getters) to be asynchronous and do some sort of event pub/sub for
> class properties around it, you can implement something like lazy
> loading for gwt.
Yes, this could be a potentially useful project, but it's not what I'm
aiming for here.

> Not sure if is usefull, I think the best way is to
> specifiy all data in the query beforehand: it saves you roundtrips to
> db and it makes you think of how to design you application.
This kind of work is specifically what lazy loading is designed to
prevent in an enterprise application. It's necessary only in a small
percentage of use cases. When it's not necessary, it's just labor-
intensive busy-work.

walden

unread,
Jun 3, 2008, 10:57:56 AM6/3/08
to Google Web Toolkit
Ryan,

Your responses confuse me. I though you were seeking a Lazy Loading
for GWT. Here you say you're not. At the beginning of the thread you
give an obviously synchronous method signature for retrieving an
object property, but you say in text that it does not have to be
synchronous. What the heck are you after?
I agree with Ping on this. I think he said what I was trying to say
above, only better. Specifically, designing network applications is
different from designing desktop (i.e., "all resources are local")
applications, and this is one of the places where that distinction
rears its head. Apps that use the net but pretend not to use the net
end up sucking -- because how the net gets used impacts user
experience so strongly. Hence all the J2EE "patterns" that sprouted
up last decade to try to convince developes to stay away from fine
grained transfers and pay attention to partial failure states that
don't exist in simpler environments.

Also, good point Ping that *most* gui programming works on the async
model, not just the web ones.

Walden

Ryan Stewart

unread,
Jun 3, 2008, 11:54:49 AM6/3/08
to Google Web Toolkit
On Jun 3, 9:57 am, walden <wmath...@aladdincapital.com> wrote:
> Ryan,
>
> Your responses confuse me. I though you were seeking a Lazy Loading
> for GWT. Here you say you're not. At the beginning of the thread you
> give an obviously synchronous method signature for retrieving an
> object property, but you say in text that it does not have to be
> synchronous. What the heck are you after?
Yes, reading back over that last post, I can see how it could be
confusing. What I meant was that the approach Ping suggested is not
what I was looking for: "...design an app expecting accessors
(getters) to be asynchronous and do some sort of event pub/sub for
class properties". That's the part that I meant I wasn't trying to do--
I'm not trying to create some client-side framework that developers
have to code to. I explicitly stated in my original post that I was
looking for a non-intrusive solution.

Here is the specific problem I'm trying to solve: Hibernate is used on
the server for data access. GWT is used to generate the client. Domain
objects/entities are passed from the server to the client, currently
using dozer to assemble to and from representative DTOs for two
purposes: 1) strip out java 1.5+ generics that GWT couldn't previously
handle and 2) to clip the object graph at appropriate places so that
the entire database doesn't get loaded and sent back to the client.

With GWT 1.5, the generics problem goes away. We'd like to do away
with the object graph clipping for a few reasons, one of which is that
the application is growing and it's becoming more and more of a pain
to make sure that our clipped object graph(s) are suitable for every
possible use case. Lazy loading solves this problem. We already have
lazy loading on the server. It should be a simple matter to port it to
the client. In fact, it *is* very simple to port to the client with
the exception of needing a synchronous call to make it work. That
problem is what this thread is all about.

When you write a GWT client, you expect to be serializing objects back
and forth between client and server. You expect that those objects
will behave the same on the client as on the server--specifically, if
you call foo.getBar() or, more importantly, parent.getChildren(), that
you will be returned a value that you can immediately operate on. On
the server, this is perfectly safe because lazy loading is done
transparently within the getBar or getChildren call. That's what I'm
trying to achieve on the client.

Despite all the informative replies, it still seems that a synchronous
call is the only way to achieve this, making it of fairly limited use.
It looks like a widely-usable solution would have to have some kind of
client-side framework to create a different way of calling methods
involving callbacks. That would get really messy.

[...]

> I agree with Ping on this. I think he said what I was trying to say
> above, only better. Specifically, designing network applications is
> different from designing desktop (i.e., "all resources are local")
> applications, and this is one of the places where that distinction
> rears its head. Apps that use the net but pretend not to use the net
> end up sucking -- because how the net gets used impacts user
> experience so strongly. Hence all the J2EE "patterns" that sprouted
> up last decade to try to convince developes to stay away from fine
> grained transfers and pay attention to partial failure states that
> don't exist in simpler environments.
>
> Also, good point Ping that *most* gui programming works on the async
> model, not just the web ones.
I think that I'd generally agree with all of that except maybe the
"use but pretend not to use" part. It's the "how" part that has a
major impact on the suckiness. I think that the real mismatch here is
trying to marry up a traditional webapp backend with a near-desktop-
like frontend. I don't know what the real solution is yet, but I
suspect that the dire lack of desktop app best practices will be
corrected in the near future as GWT and similar technologies gain
users.

quentin

unread,
Jun 3, 2008, 3:16:56 PM6/3/08
to Google Web Toolkit
Ryan,

How will you handle syncing your client-side domain model with changes
made to its server-side counterpart?

Peter Blazejewicz

unread,
Jun 3, 2008, 5:06:35 PM6/3/08
to Google Web Toolkit
hi Ryan,

again, please be informative not speculative, otherwise we will end
with thread leading nowhere (we are already on second page, spamming
"search" feature with no relevant information),
if you are creative, write your example, if you don't have real-life
scenario, here-is-one very nice, working:
http://help.apple.com/iphone/guide/
of course that's not java but here is small summary:
- it uses Cocoa/ObjC port of CoreData to javascript
- it uses Cocoa/ObjC port to javascript (yeah, there is NSObject,
NSArray, etc)
- it uses Cocoa/ObjC port of protocols/inheritance features.
- it renders that using iPhone optimized UI
*important*:
- it renders data using the same schema/data that is used on desktop
(they are nice guys at Apple, they used desktop Cocoa application to
create *persisted* & *managed* data and then read that data on web
- it uses either asynchronous or synchronous data loading: depends on
appliation requirements and current state. e.g. to load persisted
object from asynchronously loaded catalog it uses NSUrl/NSUrlRequest
to load persisted object (including base64/data url encoded images)
into application given list data controller (so it updates UI). What
is used on client application depends on its state and data definition/
importance for application and usability of your application,
give it a look, it's plain javascript, non-obfuscated and minified,
I don't know java-originated similar example (direct port to use
native platform persistance framework on web client - maybe I don't
searched too deep),

regards,
Peter

Ryan Stewart

unread,
Jun 4, 2008, 10:20:44 AM6/4/08
to Google Web Toolkit
On Jun 3, 2:16 pm, quentin <qcomps...@gmail.com> wrote:
> Ryan,
>
> How will you handle syncing your client-side domain model with changes
> made to its server-side counterpart?
>
That's a good question. I don't really have an answer for it. I think
that's a problem that applies to all of GWT in general, though, and
not just to what I'm trying to do here. With GWT, the client in the
browser essentially becomes a cache, and therefore you run into all
the normal cache-related issues of staleness, locking, and ...
whatever else.

Theoretically, you could probably set up some sort of server-push
framework to notify all connected clients of changes to the data
model, but I suspect the cost and complexity of such a thing would far
outweigh the benefits for most projects. It's just not usually worth
the hassle to make sure all of your data is as close to 100% current
as possible. If you have specific pieces that need to be near-real-
time, it would be much easier to develop code specifically for those
pieces than to write or use a generic framework.

Ryan Stewart

unread,
Jun 4, 2008, 10:49:55 AM6/4/08
to Google Web Toolkit
On Jun 3, 4:06 pm, Peter Blazejewicz <peter.blazejew...@gmail.com>
wrote:
> hi Ryan,
>
> again, please be informative not speculative, otherwise we will end
> with thread leading nowhere (we are already on second page, spamming
> "search" feature with no relevant information),
If you could be more specific about which part of my post you consider
"speculative," I'll attempt to give you more information. I don't have
a clue what you mean by "spamming" a "'search' feature"

> if you are creative, write your example, if you don't have real-life
> scenario
In the post to which you replied, I described the exact real-life
scenario that I'm working on.

> here-is-one very nice, working:http://help.apple.com/iphone/guide/
That site won't even load for me in any of my browsers. I'll try
others at home this evening.

> of course that's not java but here is small summary:
> - it uses Cocoa/ObjC port of CoreData to javascript
> - it uses Cocoa/ObjC port to javascript (yeah, there is NSObject,
> NSArray, etc)
> - it uses Cocoa/ObjC port of protocols/inheritance features.
> - it renders that using iPhone optimized UI
> *important*:
[...]
I'm not sure how this is all supposed to apply to my problem,
especially since I can't get it to load. A working app wouldn't
demonstrate the problem I'm trying to solve. This is at a lower level.

Ping

unread,
Jun 4, 2008, 11:38:58 AM6/4/08
to Google Web Toolkit
Here are my .2 cents again :)

- Programming is hard
- Programming web apps is harder
- Programming async code is even harder

- Blocking the browser while waiting for some getFoo() to return is
bad
- What if the server never responds?
- What if the server throws an exception? (ok these two can happen
in async mode, except in the first we don't have our browser
blocked :)
- What will be the state of the (this) instance when the
this.getFoo() method was called?
- How do you detect that the (this) instance is (eventually) dirty?
You have to carry a version field? I think this is related to the
problem quentin was talking about.

When you make a rpc and fetch a domain object, you are getting a
snapshot of an object at the time that is (should) be valid. You are
within a transaction. Even with lazy loading and open-session-in-view,
you are still getting a valid snapshot of whatever subset of objects -
hey, the session is open in the view phase, it is the same session,
same transaction. When you implement lazy loading, you do not have
guarantee that the lazy loaded part will correspond the already-loaded-
in-client part (sync problem), and here becomes the versioning
problem.

With that in mind, most people weight in the pros and cons of such a
"native persistence framework in web client", and the cons outweight
the pros by a large margin. It's far easier, but still hard, to design
your rpc's and domain objects and your GUI screens carefully so you
can grab consistent pieces of the domain data from the web client
while minimizing the risk for stale data.

walden

unread,
Jun 4, 2008, 1:04:48 PM6/4/08
to Google Web Toolkit
Ping,

+100, and please move your decimal point to the right a bit :-)

Walden
> > demonstrate the problem I'm trying to solve. This is at a lower level.- Hide quoted text -
>
> - Show quoted text -

Ryan Stewart

unread,
Jun 4, 2008, 2:42:45 PM6/4/08
to Google Web Toolkit
On Jun 4, 10:38 am, Ping <miguel.p...@gmail.com> wrote:
> Here are my .2 cents again :)
>
> - Programming is hard
yes

> - Programming web apps is harder
yes

> - Programming async code is even harder
I'd say "different" rather than "harder".

> - Blocking the browser while waiting for some getFoo() to return is
> bad
> - What if the server never responds?
> - What if the server throws an exception? (ok these two can happen
> in async mode, except in the first we don't have our browser
> blocked :)
yes, which is why I started this thread asking for an alternative to a
synchronous call

> - What will be the state of the (this) instance when the
> this.getFoo() method was called?
That's kinda part of the point under discussion.

> - How do you detect that the (this) instance is (eventually) dirty?
> You have to carry a version field? I think this is related to the
> problem quentin was talking about.
Yes, that's exactly what he was talking about and what my reply dealt
with.

> When you make a rpc and fetch a domain object, you are getting a
> snapshot of an object at the time that is (should) be valid. You are
> within a transaction.
[...]
> Even with lazy loading and open-session-in-view,
> you are still getting a valid snapshot of whatever subset of objects -
> hey, the session is open in the view phase, it is the same session,
> same transaction.
[...]
Okay, I was hoping nobody would bring up the transactional aspect of
it. That's a separate discussion. There are certainly considerations
to be aware of, but not many more than normal. The whole idea of what
I'm trying is to sort of extend the OSIV pattern to the client;
however, the OSIV pattern doesn't actually guarantee safe lazy loading
via transactions. The entire request is not in wrapped in a
transaction. Therefore what I'm doing is not much different, and this
whole thing goes back somewhat to the stale data discussion.
Reply all
Reply to author
Forward
0 new messages