Asynchronous client transports
------------------------------
Key: THRIFT-137
URL: https://issues.apache.org/jira/browse/THRIFT-137
Project: Thrift
Issue Type: Improvement
Components: Compiler (Java)
Reporter: Fredrik Hedberg
Priority: Minor
As previously discussed on the mailinglist, using Thrift from Google Web
Toolkit (GWT) applications (AJAX) would be nice, as it does not only allow you
to consume existing Thrift services from GWT applications, but also means that
you now can write GWT-consumable RPC services in any language (and say host
them on Google Appengine) that are practically source-code compatible with the
official GWT RPC framework.
Doing this presents two challanges:
1) The GWT compiler only supports a subset of the JRE libraries (luckily, this
is rather easy to work around).
2) As the A in AJAX hints, the only way of doing RPC is asynchronously,
something not supported by Thrift, by using the XMLHttpRequest object in the
browser.
Here's what I've done (an excerpt from the mailing-list):
--snip--
1) Created a stripped down jar of Thrift, axed most protocol, transport and
server implementations, in order to get a JavaScript-translatable version of
Thrift. I did not need to change any of the base Thrift classes, nor modify the
compiler for GWT to translate the structs, but I might have missed something
here (Mathias?).
2) Added an option for the Thrift Java compiler to generate asynchronous
service interfaces and client proxies. This is manifested as:
public class Repository {
public interface Iface {
public Document get_document(String uri) throws TException;
public int get_count() throws TException;
}
public interface AsyncIface {
public void get_document(String uri, TAsyncCallback<Document>
callback) throws TException;
public void get_count(TAsyncCallback<Integer> callback) throws TException;
}
...
This is done in line with GWT's RPC framework and gives the developer the
standard synchronous interface to implement on the server side (I use it with
embedded Jetty in a daemon) and an asynchonous interface to use in the GWT
client. AsyncCallback<T> just has a plain onSuccess(T result) method.
3) Implemented a client transport using GWT's RequestBuilder (the
XmlHttpRequest abstraction) that executes the TAsyncCallback asynchronously
when the response has been received.
4) Modified the JSONProtocol slightly to be fully JavaScript-translatable. This
could probably be more efficiently done by using GWT's JSNI framework, but I
really haven't had the time to optimize anything yet.
--snip--
This solution works really well for my problem, but it's half-assed in two
ways.
1) It only allows for asynchronous client transports (as in the case of the
XMLHttpRequest object) and not on the server side (with messages coming back in
a non-sequential order).
2) I'm not sure how to solve the client library issues. Right now, I've moved
the core classes (those required on the client (GWT) side of things) into
com.facebook.thrift.gwt, while keeping everything else where they are. This
allows the GWT compiler to translate com.facebook.thrift.gwt.* while using the
same jar both on the client and server. This is not very elegant for people not
using GWT (which I suppose is 99.99% of the audience) but short of maintaining
two separate Java client libraries, I'm not sure how to solve this issue.
The attached patch is only for the compiler, and does not produce compilable
client code without the modified client library. Just wanted to get some input
before producing a somewhat committable patch. Comments? Ideas?
--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.