Gears enabled GWT

2 views
Skip to first unread message

Jason Essington

unread,
Jun 5, 2007, 12:09:42 PM6/5/07
to Google Web Toolkit Contributors
O.K. now that Gears has been announced, and the gwt-google-apis
project includes Gears as its first api, I thought I'd start a thread
about how/where GWT could benefit from becoming Gears enabled.

1) Some folks have complained about object [de]serialization, so if
Gears is present, why not move this task off to a worker. RPC is
already asynchronous, just get this stuff out of the main ui loop.

2) LocalDB backed SuggestBox. Why not have suggestions cached by a
worker, then when a Suggest box is used the suggestions could be
served from the local data store.

3) Cache i18n Strings in the local database ... this could allow
users to change regions on the fly, and pretty much instantaneously.

4) From the Gears list, someone has already made a dictionary, so how
about a Gears backed spelling api for the RichTextEditor.


Any other ideas?

-jason

Rob Jellinghaus

unread,
Jun 5, 2007, 1:15:30 PM6/5/07
to Google Web Toolkit Contributors
GWT-generator-based ORM. Someone on the Gears list has already made a
first stab at it:

http://groups.google.com/group/google-gears/browse_thread/thread/e6e857a522c21408

I haven't looked at the implementation at all, but the code samples
seem pretty nice. A generator-based implementation could do away with
even the minimal amount of boilerplate that the code has now, and
could start adding things like ID field support, one-to-many / many-to-
many references, etc., etc.

Cheers!
Rob

Miguel Méndez

unread,
Jun 5, 2007, 1:50:53 PM6/5/07
to Google-Web-Tool...@googlegroups.com
Moving deserialization onto a worker thread would be pretty cool.  Although, since threads only communicate using strings today, how would you get the deserialized object back?  Some other form of communication?

I guess that you could always deserialize into a database...

Jason Essington

unread,
Jun 5, 2007, 2:43:21 PM6/5/07
to Google-Web-Tool...@googlegroups.com

On Jun 5, 2007, at 11:50 AM, Miguel Méndez wrote:

> Moving deserialization onto a worker thread would be pretty cool.
> Although, since threads only communicate using strings today, how
> would you get the deserialized object back? Some other form of
> communication?

Hadn't looked that closely at it yet. But that sorta leaves us in the
same boat doesn't it. deserializing to a database would work, but I
was hoping it could be a little more automatic than that. I wonder if
the worker comunication via strings is an artificial limitation, and
could allow passing of arbitrary objects in the future?

-jason


Sandy McArthur

unread,
Jun 5, 2007, 3:02:31 PM6/5/07
to Google-Web-Tool...@googlegroups.com
On 6/5/07, Jason Essington <jason.e...@gmail.com> wrote:
> I wonder if
> the worker comunication via strings is an artificial limitation, and
> could allow passing of arbitrary objects in the future?

My unreliable understanding is that JavaScript only communicates with
plugins via Strings/numbers for both portability, security, and
simplicity reasons. Otherwise plugins would need a non-trivial
understanding of JavaScript engines and their memory management
methods.

--
Sandy McArthur

"He who dares not offend cannot be honest."
- Thomas Paine

John Tamplin

unread,
Jun 5, 2007, 3:31:36 PM6/5/07
to Google-Web-Tool...@googlegroups.com
On 6/5/07, Miguel Méndez <mme...@google.com> wrote:
Moving deserialization onto a worker thread would be pretty cool.  Although, since threads only communicate using strings today, how would you get the deserialized object back?  Some other form of communication?

I guess that you could always deserialize into a database...

AFAIK, SQLite (which is used by Gears), natively stores all values as strings, so that isn't going to help you either.

--
John A. Tamplin
Software Engineer, Google

John Tamplin

unread,
Jun 5, 2007, 3:37:20 PM6/5/07
to Google-Web-Tool...@googlegroups.com
On 6/5/07, Sandy McArthur <sand...@gmail.com> wrote:

On 6/5/07, Jason Essington <jason.e...@gmail.com> wrote:
> I wonder if
> the worker comunication via strings is an artificial limitation, and
> could allow passing of arbitrary objects in the future?

My unreliable understanding is that JavaScript only communicates with
plugins via Strings/numbers for both portability, security, and
simplicity reasons. Otherwise plugins would need a non-trivial
understanding of JavaScript engines and their memory management
methods.

It depends on which plugin method you refer to -- NP runtime (which is supported pretty much everywhere besides IE) provides low-level acces to the JSVM (which we will need to implement hosted mode as a plugin), and I believe ActiveX controls in IE can exchange COM VARIANTs directly with the JSVM -- I don't know about others.

Miguel Méndez

unread,
Jun 5, 2007, 4:01:39 PM6/5/07
to Google-Web-Tool...@googlegroups.com
I did not mean to pour cold water on the discussion.  I just wanted to point out that it is a limitation that should be explored.  I'd be willing to bet that there is probably a creative solution to this... or maybe a feature request for Gears :)

On 6/5/07, Jason Essington <jason.e...@gmail.com> wrote:

Rob Jellinghaus

unread,
Jun 5, 2007, 5:30:47 PM6/5/07
to Google Web Toolkit Contributors
On Jun 5, 1:01 pm, "Miguel Méndez" <mmen...@google.com> wrote:
> that there is probably a creative solution to this... or maybe a feature
> request for Gears :)

Actually, there's a very strong architectural reason why worker
threads only communicate by strings. It's to avoid sharing a heap.
If worker threads shared a heap and could directly pass objects back
and forth, then suddenly you'd be faced with supporting full threading
and synchronization in Javascript, because now the worker thread would
be mutating the same Javascript heap objects as the main heap.
Whammo, synchronization rears its horribly ugly head. That's not
something the Gears team is ever likely to tackle, because the win is
just not worth the cost.

... Hmm. Actually, now that I think about it a bit more, there
*could* be a creative solution to this. It would have to involve
sharing a single heap, but *not sharing any heap objects.* The main
thread -> worker thread interface would have to religiously copy every
single Javascript object graph sent back and forth, to prevent any
sharing of any kind whatsoever.

Doing this could be something like implementing the Singularity
research operating system's model of "software isolated processes":

http://research.microsoft.com/os/singularity/publications/mspc2006_deconstructingisolation.pdf

Read that paper if you want to understand the design space here a lot
more.

The main benefit would be much higher potential bandwidth
communication between Gears threads, with much, much more room for
native optimization of the inter-thread object copying. However, it
would also be no small amount of work! So don't expect it anytime
soon....

Cheers!
Rob

John Tamplin

unread,
Jun 5, 2007, 5:44:22 PM6/5/07
to Google-Web-Tool...@googlegroups.com
On 6/5/07, Rob Jellinghaus <rjelli...@gmail.com> wrote:
... Hmm.  Actually, now that I think about it a bit more, there
*could* be a creative solution to this.  It would have to involve
sharing a single heap, but *not sharing any heap objects.*  The main
thread -> worker thread interface would have to religiously copy every
single Javascript object graph sent back and forth, to prevent any
sharing of any kind whatsoever.

Actually, I think you could do it like C++ auto_ptr's -- each object is reachable only from one "thread"'s roots -- so when you pass it your reference is removed and it appears in the target thread.  You would have to have some way to do a deep copy (you could do it in JS, but it would really slow and not clear how you could make sure you didn't keep any other reference to any of the objects).

Miguel Méndez

unread,
Jun 6, 2007, 9:44:39 AM6/6/07
to Google-Web-Tool...@googlegroups.com
It seems that eval() plus a 1:1 mapping of JSON export of a GWT class could do the trick.
--
Miguel

John Tamplin

unread,
Jun 6, 2007, 10:52:44 AM6/6/07
to Google-Web-Tool...@googlegroups.com
On 6/6/07, Miguel Méndez <mme...@google.com> wrote:
It seems that eval() plus a 1:1 mapping of JSON export of a GWT class could do the trick.

But is that actually saving any work?  It seems like that is essentially the same thing as the RPC deserialization that we wanted to move into the worker thread in the first place.

That could be useful in general for passing objects between threads, but I don't think it helps in the specific case that started this discussion.

Toby Reyelts

unread,
Jun 6, 2007, 11:04:43 AM6/6/07
to Google-Web-Tool...@googlegroups.com
Echoing my thoughts exactly.

Really the important thing is that we make de-serialization not block the UI thread in ALL cases. That's going to mean working IncrementalCommand into the mix, regardless of Gears. And as someone else noted, the RPC is going over the network anyway, so there's already latency involved. I'm not sure that there's a ton of benefit to offloading it onto a separate thread.

Scott Blum

unread,
Jun 6, 2007, 12:21:58 PM6/6/07
to Google-Web-Tool...@googlegroups.com
On 6/6/07, John Tamplin <j...@google.com> wrote:
On 6/6/07, Miguel Méndez <mme...@google.com> wrote:
It seems that eval() plus a 1:1 mapping of JSON export of a GWT class could do the trick.

But is that actually saving any work?  It seems like that is essentially the same thing as the RPC deserialization that we wanted to move into the worker thread in the first place.

No, Miguel's right, we actual could save a lot of work in the UI thread.  The idea would be to translate the flat-form wire format into a "localized" script that will instabuild the object graph against the actual symbols in the compiled code.

Abstracted example:

Wire format:

['com.example.Foo', 'java/lang/String', 'fieldAValue', 'java/lang/Integer', 3]

Instabuild format:

$_ = new Foo(), $foo_ctor($_), $_.fieldA = 'fieldAValue', $_.fieldB = Integer_ctor(3), $_

See what I mean?  You start with a data format that must be assembled and end with a string that can just be eval'd into the actual objects you want.

BTW: The reason the server couldn't simply send the client a directly-evalable string is that the server doesn't know the obfuscated symbol names of the various fields and constructors.  If the server DID know those symbols, we could probably make deserialization an order of magnitude faster.  But that's a separate discussion. :)

Jason Essington

unread,
Jun 6, 2007, 12:37:05 PM6/6/07
to Google-Web-Tool...@googlegroups.com
cool! now the trick is, how do we get the code into the worker thread?

Since we've got to pass the executable javascript to the worker as a string ...

This is probably a discussion for another thread, but GWT+Gears doesn't currently have a mechanism for getting code into a worker without hand coding javascript. and at the time that the javascript is coded, there is not much knowledge of the symbols and such used in the compiled code.

-jason

Toby Reyelts

unread,
Jun 6, 2007, 12:53:23 PM6/6/07
to Google-Web-Tool...@googlegroups.com

I don't know. That sounds like a good argument to me for improving the wire format in general, across all cases, as opposed to only for Gears. I really don't want to see us throw in Gears' specific optimizations that should really apply to all users.



Scott Blum

unread,
Jun 6, 2007, 1:08:39 PM6/6/07
to Google-Web-Tool...@googlegroups.com
On 6/6/07, Toby Reyelts <to...@google.com> wrote:
I don't know. That sounds like a good argument to me for improving the wire format in general, across all cases, as opposed to only for Gears. I really don't want to see us throw in Gears' specific optimizations that should really apply to all users.

Maybe, but for the purposes of brainstorming I think it's a good discussion.

Robert Hanson

unread,
Jun 7, 2007, 8:05:25 AM6/7/07
to Google-Web-Tool...@googlegroups.com
I saw that post and was thinking the same thing, so I started working on a simple generator.  I should have working code and a write-up posted by Monday.

The only potential issue that I am running into so far is that GWT.create() can only take a single argument.  This will make it difficult to handle associations between data objects.

Can anyone think of another way to get all of the data types passed to a single generator for inspection?  Maybe it is easy to add a new create() method that takes an array of classes?

Rob


On 6/5/07, Rob Jellinghaus <rjelli...@gmail.com> wrote:

Scott Blum

unread,
Jun 7, 2007, 9:35:40 AM6/7/07
to Google-Web-Tool...@googlegroups.com
Hi Robert,

Without knowing a lot about the details, here's an example of how you can pass "multiple types" to a generator.

class FooBarAssociation implements MyAssociationMarkerInterface {
  Foo foo;
  Bar bar;
}

Then when you GWT.create(FooBarAssociation.class), your generator can inspect the FooBarAssociation type and realize it contains multiple field types.

This is analgous to how RPC inspects the entire interface that's passed-in and walks the type tree from there.

Scott

Robert Hanson

unread,
Jun 7, 2007, 11:13:06 AM6/7/07
to Google-Web-Tool...@googlegroups.com
I'll have to think about that, but it is a different direction than I was headed.  Here is some sample code.

[From the EntryPoint]

try {
    GearsDataStore ds = (GearsDataStore) GWT.create(MyData.class );
    ds.createTable();
    ds.save(new MyData());
    MyData[] data = (MyData[]) ds.loadAll();
    ...
    ds.deleteTable();
    ds.close();
}
catch (DatabaseException e) {
    e.printStackTrace();
}

The data store is generated from the MyData bean.  The bean contains annotations that describes the table, and eventually could also describe relationships between this bean and other beans.

[MyData.java]

/**
 * @gears.table (  name = MyDataTable  )
 */
public class MyData implements GearsDataObject
{

    /**
     * @gears.id (length=100)
     */
    private String email;
   
    /**
     * @gears.column (name=firstName, length=25)
     */
    private String fname;

    /**
     * @gears.column (name=lastName, length=25)
     */
    private String lname;

    /**
     * @gears.column (length=3)
     */
    private Integer age;

    /*** getters/setters follow ***/
}

If I did it the way you suggested, I don't think I have access to the annotations in the referenced classes (Foo and Bar).  Do I?

Rob

Scott Blum

unread,
Jun 7, 2007, 11:40:35 AM6/7/07
to Google-Web-Tool...@googlegroups.com
Sure.  You can totally crawl the type tree and look at the metadata of any types.  RPC has to do exactly that for handling @gwt.typeArgs annotations.

In fact, if you want to reference other types from your rebound type, annotations is another way to do that.  I'd look through the RPC generator code if you haven't before.

Scott

On 6/7/07, Robert Hanson <iamrobe...@gmail.com> wrote:
I'll have to think about that, but it is a different direction than I was headed.  Here is some sample code.

[From the EntryPoint]

try {
    GearsDataStore ds = (GearsDataStore) GWT.create(MyData.class );
    ds.createTable();
    ds.save(new MyData());
    MyData[] data = (MyData[]) ds.loadAll();
    ...
    ds.deleteTable();
    ds.close();
}
catch (DatabaseException e) {
    e.printStackTrace();
}

The data store is generated from the MyData bean.  The bean contains annotations that describes the table, and eventually could also describe relationships between this bean and other beans.

[MyData.java]

/**
 * @gears.table (  name = MyDataTable  )
 */
public class MyData implements GearsDataObject
{

    /**
     * @ gears.id (length=100)

Robert Hanson

unread,
Jun 7, 2007, 11:44:32 AM6/7/07
to Google-Web-Tool...@googlegroups.com
> I'd look through the RPC generator code if you haven't before.

I haven't.  I'll check it out.  Thx.

Rob

On 6/7/07, Scott Blum <sco...@google.com> wrote:
Sure.  You can totally crawl the type tree and look at the metadata of any types.  RPC has to do exactly that for handling @ gwt.typeArgs annotations.

Rob Jellinghaus

unread,
Jun 7, 2007, 5:43:52 PM6/7/07
to Google Web Toolkit Contributors
Glad you're looking at this, Robert! Please keep me posted, I'd love
to be an alpha tester :-)

Cheers!
Rob

Ray Cromwell

unread,
Jun 7, 2007, 6:08:24 PM6/7/07
to Google-Web-Tool...@googlegroups.com

I would add the following wish-list idea, tossed around at GDD between Rob and I.

Implement an HQL-like query language *statically evaluated at compile time*, so you can write code like:

GearsDataStore gs=...

public interface MyDataQuery extends GearsHQLQuery {

  /**
   * @gwt.hql from MyData m where m.email like :1
   */
  Iterator findByEmail(String emailPattern);

  /**
   * @gwt.hql from MyData m where m.lastName like '%:1%' and m.age = :2
  */
  Iterator findByLastnameAndAge(String lastName, int age);
}

MyDataQuery query = (MyDataQuery)GWT.create(MyDataQuery.class);
query.setDataStore(gs);

Iterator  i = query.findByEmail("@gmail.com");
...
 
Since we're doing this in a Generator, we can rip and reuse Hibernate's HQL parser, create a custom dialect for Gears, have it translate the requested HQL into static Gears SQL, and then insert magic code to prep the parameters and de-serialize the result into MyData objects. :)

-Ray

Rob Jellinghaus

unread,
Jun 7, 2007, 7:06:03 PM6/7/07
to Google Web Toolkit Contributors
OK, for the record, I think there are about 50 other features that are
higher priority than that one :-) Specifically, lazy loading and
cascade are both more important than anything HQL-like. Once we do
get to querying, I would think that a criteria-like API would be scads
of times easier than anything HQL-ish.

(HQL generated to SQL on the server *would* be cool, though, huh?)

Cheers!
Rob

Ray Cromwell

unread,
Jun 7, 2007, 7:19:46 PM6/7/07
to Google-Web-Tool...@googlegroups.com

Doing Hibernate-style cascades might be too ambitious for a first run, maybe just doing iBatis-style functionality would be better for an initial version. No
cascades/lazy loads/outer joins, etc. Just SQL->Object mapping?

Rob Jellinghaus

unread,
Jun 8, 2007, 1:30:23 AM6/8/07
to Google Web Toolkit Contributors
That's what I assume Rob Hanson is working on, and certainly sounds
fine to me.

Cheers!
Rob

Robert Hanson

unread,
Jun 8, 2007, 8:56:21 AM6/8/07
to Google-Web-Tool...@googlegroups.com
> That's what I assume Rob Hanson is working on

Baby steps ;)

Rob

Fushion

unread,
Jun 8, 2007, 9:42:39 AM6/8/07
to Google Web Toolkit Contributors
Gears made me start thinking... (ouch!)

As GWT apps will become larger as the time goes by,
we'll surely see some apps that will become too large to fit into one
decently sized javascript files.
Especially Enterprise applications will need a lot of libraries.

GWT could in the future (GWT release 8.275 RC1 ;-) ) have some kind of
lazy- or eager classloading mechanism, where the compiled JS code for
the libraries could be cached in Gears.

Just a mindspin...


Greetz,
Menno van Gangelen.

The Class Connection

unread,
Jun 8, 2007, 2:08:20 PM6/8/07
to Google-Web-Tool...@googlegroups.com
Reply all
Reply to author
Forward
0 new messages