On Oct 26, 2007, at 11:43 PM, Mattias Jiderhamn wrote:

> Hi list.
> I am considering Hessian for a specific task in the project I am  
> working
> at, namely synchronous messages within the same application, that
> requires different session/context for sender and receiver. (This  
> would
> also allow us to separate client/server in into different applications
> in the future).
>
> AFAIK, Hessian does not support any type of sessions spanning several
> request, in the manner that SOAP APIs like Axis does.

Correct.  It would be possible to create something like that, but it  
would complicate the client and server, so it's something we've avoided.

> This poses a
> problem to us. Since we will transfer N instances of binary data  
> within
> a single transaction. I'm thinking something like this
>   hessianService.prepareTransaction();
>   for(...; i < N; ...) {
>     hessianService.transferJavaData(foo);
>     hessianService.transferBinaryData(inputStream);
>   }
>   hessianService.commitTransaction();
>
>
> Here is my idea for solving this:
> In the prepareTransaction() method of the service, I will generate a
> unique ID (possibly by having Resin generate a HTTP session). This ID
> will be used as the key in a WeakHashMap. The value of the Map is an
> object (let's just pretends it's a simple List) that queues the data
> (and references to binary data in temp files on disk) until we are  
> ready
> to commit.
> There would also be a "reaper queue", that holds a (strong)  
> reference to
> the data queue object (i.e. List), and a timeout (milliseconds from
> January 1, 1970). This time out queue has a reaper thread, that will
> wake up now and then, removing the strong references to the queues  
> that
> have timed out, and thus letting the garbage collector remove them  
> from
> the WeakHashMap in case the client is unable to commit the  
> transaction.
>
> The session ID is returned to the client, and provided by the  
> client in
> all subsequent requests, so that the data queue can be found. On every
> (transferX()) call to the service, the timeout in the reaper queue is
> also updated. When commiting, everything related to this "session" is
> explicitly removed, of course.

>
> Qestions:
> - Am I making this more complicated that neccessary? Would a simple
> try/finally on the client, removing all data regardless of outcome, be
> enought (until we actually separate the applications)?

There are a few things you want to change.

First, you would need to add the id to each method.   Unless Hessian  
adds an out-of-message session context, it's better to make that kind  
of cookie explicit.  The Hessian API can be a little more ugly than  
the API that you present to the application.  You can hide the cookie  
behind another facade.

> - Is there a better, yet robust, way to do this?

There are some things you'll want to change.

First, there should only be a single Map containing your sessions.   
The separate List isn't needed.  So there's no real need for a  
WeakHashMap.  WeakHashMap is normally for things like Class and  
ClassLoader.  You really don't want to use it for String keys.

The Value of the HashMap will contain your session and also the  
expires time.  Your reaper can walk along the HashMap.entrySet(),  
look for timeouts of the Value and remove as necessary.  The value  
would look something like the following.

class SessionValue {
   SessionData getData();
   void access(); // updates expires time
   boolean isExpired();
}

The basic idea is the same as you've proposed.  That's basically how  
you implement long-lived sessions.

> - Should I be using something other than Hessian...?

You could actually look at EJB stateful session beans.  It's  
essentially the same model as you're looking at.  You can even use  
Hessian to communicate with them.

> Is there a way to
> use JMS without having to keep all the binary data in memory?

I'm not sure JMS would be appropriate.  Normally, JMS messages are  
standalone.  If you sent multiple JMS messages to some target which  
would collect them and wait for a commit, you'd still need to create  
a session to hold all the pending messages, which would be exactly  
the same issue as you have with Hessian.  And the JMS queuing  
machinery wouldn't really benefit that case.

-- Scott

>
> Thanks in advance,
>
>  /Mattias Jiderhamn
>
>
> _______________________________________________
> hessian-interest mailing list
> [email protected]
> http://maillist.caucho.com/mailman/listinfo/hessian-interest



_______________________________________________
hessian-interest mailing list
[email protected]
http://maillist.caucho.com/mailman/listinfo/hessian-interest

Reply via email to