Re: Hessian PHP implementation

From: Radu-Adrian Popescu <radu.popescu@xxx.com>
Date: Fri Jan 14 2005 - 04:16:43 PST

1. Error handling
- Client side
HessianCPP uses a small, SSL-enabled, POST-only HTTP library.
This throws (*) sslpp::exceptions::http_exception.
The hessiancpp codebase defines another two exceptions:
(*) hessian::exceptions::io_exception
(*) hessian::exceptions::fault_exception
So we have three exception types, each of those on a different layer in the
client-server communication:
- http_exception at the TCP/HTTP level;
- io_exception at the Hessian protocol level;
- fault_exception for server-side errors (these _do not_ include 404, 500 and
friends, i.e. they are exclusively hessian-serialised exceptions from the reply).
We really don't care about the server-side stack trace, except for the embedded
exception name (when using exceptions that are thrown by code to signal truly
exceptional conditions, such as database failure).
I also think that there's really no point in having the server-side stack trace
in the client. I mean it's not like the client cares about a list of some thirty
Java classes on the backtrace; the client made a call and the server went awry,
nothing it can do about it. And obviously exception logging should be
implemented on the server side, so no need to serialise Kb of maps to the client
for a useless backtrace. Maybe some of you will disagree, but I think that
writing services that catch all exceptions and throw user exceptions in a
controlled fashion, and make use of proper error logging is the way to go. And
this I hold for all clients, not just C++.
I also think the server-side hessian Java implementation should not make use of
some logging package that would slow it down, and leave the error handling to
the service implementation.

Regarding error handling when exceptions are missing (PHP), how about an
exception handler function pointer thing ? Maybe not the best idea...

Regarding the method overloading, I've not run into it as yet and provided not
support for it in hessiancpp, but I've talked to someone who has (Matt from
Javalobby, see http://javalobby.org/nl/archive/jlnews_20041207o.html#newsfront)
and pointed him to
http://www.caucho.com/resin-3.0/protocols/hessian-1.0-spec.xtp#Methods-and-Overloading

He replied saying thanks, he's already and unknowingly done it that way.
So the least I can say here is that the assertion that two methods having the
same name and different signature is forbidden is wrong, and overloading is in
the spec.

Regarding the Gzip compression: "If you use HTTP headers you could keep it out
of the Hessian internals.". Well, here's how I did it:
- changed com.caucho.hessian.HessianServlet and
1) look-up User-Agent header;
2) if the user-agent is Flash, we pre-un-escape the input stream;
3) prepare a ByteArrayOutputStream to hold reply;
4) invoke with input stream and our output stream;
5) if the client is Flash, escape the reply data;
6) if the client is hessiancpp, if the reply size exceeds a threshold, gzip it;
7) pour the reply to the client;
8) in C++ the server call proxy test the 1st four bytes of the reply for the
gzip magic and de-compresses if found, then passes the de-compressed reply to
the same channel of processing as usual.
Now looking at the above I find the process quite straight-forward. We may want
to add usage of another HTTP header, namely the standard Accept-encoding header
("gzip" or "deflate"), to make things a bit more general on the compression side
and maybe also on the Flash escaping side. This remains to be thought through
properly though, as we may also be able to use standard web server compression
for Flash using mod-gzip or mod-deflate (Flash calls server using browser and
browsers generally are able to grok gzip/deflate). The Flash issue is that it
does not have a API-accessible, native (meaning C/C++) implementation of any
compression algorithm. The SWF itself uses Gzip if I'm not mistaken, so the
ActiveX/Netscape component does have this built in, but it's just that you can't
get to it from the API, and writing one in AS does not look pretty.

Regarding binary XML, I don't an opinion on that as yet. I've fiddled with
S-expressions instead and I find them much more agreeable (than XML). Maybe I'm
naive, but I wrote a non-recursive S-expression parser:
[root@xxx sexpp]# wc -l *.java

   81 bytearray.java
  113 Parser.java
   48 sexp_input_stream.java
  242 total

in yes, 242 lines of code, including a very fast resizeable byte array and a
simplistic, over-a-string input stream. It parses S-expressions into trees,
using DefaultMutableTreeNode from *ugh* Swing. It also supports binary data by
using (optionally) length-prefixed strings.
Prior art suggests in-memory, binary representation of s-expressions is rather
efficient.
You may want to take a look here: http://theory.lcs.mit.edu/~rivest/sexp.txt for
  further information.
And to think XML 2.0 is in the works...

All in all, except for the bugs, I'm pretty happy with the current
Caucho/Hessian implementation. Not that happy with the c++ implementation though
:). I've also implemented a code generator for C++, written in Java, that
outputs C++ classes matching those used by the service's methods, and also all
the [de]serialisation, exception handling and all that's needed to basically
provide a C++ project with the service invocation stubs. Pretty much like what
an IDL compiler does, or a WSDL-to-code (.NET's wsdl.exe is a good example)
does, except here we don't have an IDL but the service's interface class.

Wow, this was a long email. I hope it will spring up the discussion.

Cheers,

-- 
Radu-Adrian Popescu
CSA, DBA, Developer
Aldrapay MD
Aldratech Ltd.
+40213212243

Received on Fri 14 Jan 2005 04:16:43 -0800

This archive was generated by hypermail 2.1.8 : Thu Sep 28 2006 - 20:16:40 PDT