4

I need some advice on how propagating server-side changes of entities to the client is best handled with GWT's RequestFactory.

Let us assume we have two EntityProxies, a PersonProxy and a PersonListProxy (which has a getter for a List). Assume that the client has fetched a PersonList and a Person from the server.

In case the client is editing one of these proxies and firing a request, the machinery of RequestFactory (if I have understood the principles correctly) will fire an EntityProxyChange event if it detects changes done by server code (so that the client can update its display of the entities, for example).

Now assume that the server is changing its entities outside of a request by this client (e.g. due to another client calling the server) so that this client would see another version if it fetched the Person or the PersonList again.

My question is what is the best way inside the RequestFactory framework to tell the client of the changes (and to reuse as much of the machinery as possible)? We can assume that I have a way to send simple messages from the server to the client (e.g. Google App Engine's channel API or server-sent events).

One idea could be that the server sends over this channel a message telling that a Person or a PersonList with a specific id has changed. The client code handling the receipt of these messages could then use RequestFactory to re-fetch (e.g. find) the entity. This change should then be propagated to other parts of the client by an EntityProxyChange event.

Is this the way to go? (And in case that the client already has the current version of the entity, e.g. because the server was dumb and notified the client of changes the client itself made, would the triggered re-fetch just transport a few bits of metadata and not the whole entity again?)

ADDED:

Thinking a bit more about it, I wonder how EntityProxyId's can be generated for the server-sent event channel. When an entity on the server changes, the server only has the server id. It can then send it to the client, of course, but the client only knows of EntityProxyId's. Of course, I could add a getId() (in addition to getStableId()) to each EntityProxy, but it looks as if this would add redundant data to every server response.

Marc
  • 4,327
  • 4
  • 30
  • 46
  • Very interesting question! Just a note: the "diff" is always from client to server in RF (this is what the `edit()` is for on the client-side: track changes so a diff can be made) – Thomas Broyer Mar 29 '13 at 09:31
  • Ah, so you are saying a `find` always creates a new EntityProxy and does not take any already existing EntityProxies with the right id and version into account, right? And that I should be careful to return small entities in my requests as no diff with client knowledge is made here, right? – Marc Mar 29 '13 at 09:40
  • Understood... RequestFactory cannot not know which parts of a server-side entity have changed so it would be an all or nothing. – Marc Mar 29 '13 at 09:48
  • @Marc Hi, I am very interested on knowing how you implemented this finally. I have the same challenge ahead and I am also using RF and GAE on the server side. Can you create an answer detailing your implementation? Thanks a lot! – manubot Jan 17 '14 at 09:49

1 Answers1

2

Well, I realize that my post isn't precise answer to your question, but it's just my experience. In fact, there is just a question how to deliver data from server to client. I faced with some task couple years ago, and found for yourself an approach that make my life easier. To explain it, I want to specify my reasons:

  • You have to have full data delivery by requesting it from client - it's straight, natural way to requesting data;
  • You don't want to create and support 2 different models of full data delivery: one by requesting from client and second by pushing from server;
  • But you need to inform client about some changes on server side;

So, now I'm building my architecture using following approach:

  1. Build full classical client-server API for data delivery - so you can load and refresh your application in natural way even if your pushing functionality is blocked or broken.
  2. Define key information that may be changed on server side and should be delivered to client via push mechanism.
  3. Create small push message construct(s) that will deliver to client just a notification about changes - no any valuable data should be delivered this way - just keys which data was changed.
  4. All that is needed to do on client when it receives such notification is just to get/refresh data from server in natural client-server way that is already supported.
  5. Server logic shouldn't bother client side by huge amount of notifications - sometimes is more effective do not deliver changes, but just refresh everything.

Hope this helps.

domax
  • 649
  • 3
  • 13
  • Hi domax, how do you build your push message? I am investigating about it and I can find Channel API for GAE but I can't find any GWT library that maps it on the client (and I am not good at writing JS) – manubot Jan 14 '14 at 22:55
  • I use https://github.com/Atmosphere/atmosphere See also an answer here: http://stackoverflow.com/questions/9825849/using-atmosphere-for-gwt-comet – domax Jan 16 '14 at 20:33
  • It changed since my last visit there. Now GWT support is here: https://github.com/Atmosphere/atmosphere-extensions/wiki/Atmosphere-GWT-2.0 – domax Jan 16 '14 at 20:39