views:

63

answers:

2

I'm sending object IDs back and forth from client to server through the GWT RPC mechanism. The ids are coming out of the datastore as Longs (8 bytes). I think all of my ids will only need 4 bytes, but something random could happen that gives me a 5-byte (or whatever) value.

Is GWT going to be smart about packing these values in some variable-length encoding that will save space on average? Can I specify that it do so somewhere? Or should I write my own code to copy the Longs to ints and watch out for those exceptional situations?

Thanks~

+4  A: 

GWT uses gzip compression for responses with a payload of 256 bytes or greater. That should work well if you have a lot of zero bytes in your response.

From RemoteServiceServlet.shouldCompressResponse:

Determines whether the response to a given servlet request should or should not be GZIP compressed. This method is only called in cases where the requester accepts GZIP encoding.

This implementation currently returns true if the response string's estimated byte length is longer than 256 bytes. Subclasses can override this logic.

So, the server first checks if the requester (the browser, usually) accepts GZIP encoding. Internally, java.util.zip.GZIPOutputStream is used - see RPCServerUtils. On the client side, it's the browser's job to decompress the gzipped payload - since this is done in native code, it should be fairly quick.

hambend
Are you sure? Could you provide a link to the documentation or somewhere else where this is mentioned? Gzipping the payload usually is the job of the HTTP server, not the application's it's serving.
Igor Klimer
I'm not sure if it's documented anywhere but the source code doesn't lie. The inner workings of RemoteServiceServlet are surprisingly easy to follow, for the grand tour start reading at processPost but the relevant portion here is writeResponse (and so also RPCServletUtils.writeResponse). It's all done in a HTTP conformant way, setting the content encoding header, so decompression is handled automatically by the browser.
hambend
@hambend: That's interesting, because JS is quite slow when doing things like encoding/compressing etc (depends on the browser). I imagine, this could be a problem when handling large requests (say 100kB). I haven't tried client side gzipping, but I did some experiments with RC4-encryption, and IE issues slow script warnings pretty soon. So is there an option to turn gzipping off?
Chris Lercher
@hambend I've never heard of this either, do you have a reference link?
Arthur Kalmenson
Nice find hambend! I've checked the sources and indeed that's what's happening - I updated your answer with the relevant information, feel free to brush it up :) (it was too much information for a comment and another answer was rather pointless).
Igor Klimer
Is this saying that GWT will gzip your output regardless of whether you have an HTTP server in front that's already doing the compression? Interesting...
Arthur Kalmenson
Thanks Igor, looks good. @chris_l: My understanding is that decompression is a native function in most browsers rather than something handled by JS. In any case, you can disable it by overriding shouldCompressResponse in your servlet to always return false, although perhaps a check against the user agent here would be more appropriate.
hambend
@Arthur: It seems so. To be fair servlet containers only have minimal settings for enabling compression, and I suspect it's only applied automatically to static content. A quick google for "java servlet gzip compression" shows that most (all?) implementations feature the use of GZIPOutputStream in some way or another.
hambend
@hambend: huh, you learn something new every day :)
Arthur Kalmenson
@hambend: Ah, I thought it would also be done for the request, not just for the response. I sometimes have large requests with a lot of `long` values. I don't think the browser can do it natively for requests (?)
Chris Lercher
+4  A: 

As stated in the GWT documentation.

long: JavaScript has no 64-bit integral type, so long needs special consideration. Prior to GWT 1.5, the long type was was simply mapped to the integral range of a 64-bit JavaScript floating-point value, giving long variables an actual range less than the full 64 bits. As of GWT 1.5, long primitives are emulated as a pair of 32-bit integers, and work reliably over the entire 64-bit range. Overflow is emulated to match the expected behavior. There are a couple of caveats. Heavy use of long operations will have a performance impact due to the underlying emulation. Additionally, long primitives cannot be used in JSNI code because they are not a native JavaScript numeric type.

If your ids can fit in an Integer, you could be better off with that. Otherwise, if you're using a DTO, make the ids a double, which actually exists in Javascript.

Arthur Kalmenson