dev@grizzly.java.net

[Fwd: SEDAting ;-) synchronous protocols using continuations]

From: Jeanfrancois Arcand <Jeanfrancois.Arcand_at_Sun.COM>
Date: Thu, 28 Aug 2008 13:06:06 -0400

-------- Original Message --------
Subject: SEDAting ;-) synchronous protocols using continuations
Date: Thu, 28 Aug 2008 18:55:55 +0200
From: Stefano Bagnara <apache_at_bago.org>
Reply-To: dev_at_mina.apache.org
To: dev_at_mina.apache.org

Hi all,

in the last days I played with commons javaflow (continuation library).

I want to get a synchronous client and make it run asynchronously
without altering its code, because the code is much more clean to be
read than a SEDA/event based approach.

I know similar libraries have to do much with the stack/local memory and
they may be a performance bottleneck, but I wanted to give it a try and
understand the real overhead.

Here is a Proof of Concept:

My dummy synchronous client:
http://people.apache.org/~bago/netflow/site/xref/org/apache/james/netflow/rewrite/TesterClient.html

The network abstraction is the Transport: basically it allow you to
read/write lines in a blocking way.
http://people.apache.org/~bago/netflow/site/xref/org/apache/james/netflow/Transport.html

As the first step I implement an "in vm" test that simply implements the
above transport using mina against a mina backed Echo-VMPipe-transported
server.

Here is the mina transport:
http://people.apache.org/~bago/netflow/site/xref/org/apache/james/netflow/MinaTransport.html


Now I want to make it asynchronous without changing the TesterClient
source code.

I wrote a ContinuingMinaTransport:
http://people.apache.org/~bago/netflow/site/xref/org/apache/james/netflow/rewrite/ContinuingMinaTransport.html
this transport simply take care to suspend the execution of the program
each time an IoFuture is submitted.
It stores the current future in the Continuation context
(http://people.apache.org/~bago/netflow/site/xref/org/apache/james/netflow/MinaFutureContext.html)

and then suspend.
At the same time it also adds a the MinaFutureContext as a listener of
the future. The MinaFutureContext will notify its parent
MinaContinuationContext object when this future is ready so that the
continuation executor can "continue" the processing for this session.

The MinaContinuationContext simply have a map of futures and their
associuated suspended continuation, and then have a list of ready to be
resumed futures.

MinaFutureContext.getReadyContext() returns if the processing is
completed otherwise block until a future is completed and ready to be
processed.

Here is the main test class:
http://people.apache.org/~bago/netflow/site/xref/org/apache/james/netflow/Test.html

Note that I have to use a ContinuationClassLoader and a factory in order
to let javaflow instrument my protocol classes and make them suspendable.

The test simply run the protocol either in standard mode or in the
SEDAted/continuation mode. It runs 1000 transactions in threadNumber
threads.

And here are the results for a single thread:
1) synchronous, sequential connectiosn: 1000ms
2) SEDAted classes: 4000ms

1000 connections means 10000 reads + 10000 writes, so a total of 20000
events (and continuations).

I think this is an interesting result because this should show the
overhead of javaflow in the worst scenario. IN fact I have an in jvm
protocol so there is no delay at all for the network, but if I simply
add 1ms of delay for every read/write action the synchronous runner will
of course take 20 seconds more, while the SEDAted runner will run
smoothly and without using 1 thread per connection.

If anyone wants to play with the code I uploaded it to my p.o.a home:
http://people.apache.org/~bago/netflow/

WDYT? Is this an useless approach? Does it worth using continuations and
SEDAified protocols instead of 1 thread per connections or the
continuations overhead is greater than the thread overhead?

Stefano