Can support async read/write be used outside of Comet?

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

Can support async read/write be used outside of Comet?

Luiz Hamilton R L Soares
Hi,
 
I'm working with Grizzly about two months. It is the core of a LBS Gateway here in Brazil. It is working fine and my code is very simple. I use
Controller(), TCPSelectorHandler() classes and a filter, ReadFilter().
 
Well, now I need to implement an Async Server so I can write to a client without a need to wait for a message. Nowadays I can send a message to a client only after my grizzly server receive a message from the client (My TCP server is working like a UDP server!!).
 
I'm reading Grizzly ARP source code, but I can't understand how to use it in a TCP Server. There is an example of ARP, but it is for a HTTP server. 
 
Today I read an answer from Jeanfrancois Arcand in a discuss in this mailing list in 13 Jun 2007 where he was working with the Ericsson team who have requested async write to replace their NIO implementation with Grizzly.
 
Anyboy know if JFA generalize the implementation so it can be used outside of Comet?
 
Thanks a lot,
 
Luiz Soares

Flickr agora em português. Você clica, todo mundo vê. Saiba mais.

Reply | Threaded
Open this post in threaded view
|

Re: Can support async read/write be used outside of Comet?

Jeanfrancois Arcand-2
Hi Luiz,

Luiz Hamilton R L Soares wrote:

> Hi,
>  
> I'm working with Grizzly about two months. It is the core of a LBS
> Gateway here in Brazil. It is working fine and my code is very simple. I
> use
> Controller(), TCPSelectorHandler() classes and a filter, ReadFilter().
>  
> Well, now I need to implement an Async Server so I can write to a client
> without a need to wait for a message. Nowadays I can send a message to a
> client only after my grizzly server receive a message from the
> client (My TCP server is working like a UDP server!!).
>  
> I'm reading Grizzly ARP source code, but I can't understand how to use
> it in a TCP Server. There is an example of ARP, but it is for a HTTP
> server.

Right.

>  
> Today I read an answer from Jeanfrancois Arcand in a discuss in this
> mailing list in 13 Jun 2007 where he was working with the Ericsson team
> who have requested async write to replace their NIO implementation with
> Grizzly.

Right :-) We are still discussing it (was an item on our last meeting,
which I unfortunately missed).

>  
> Anyboy know if JFA generalize the implementation so it can be used
> outside of Comet?

Can you elaborate exactly on what you are looking at? With Comet, async
read and write are supported, but also the SelectionKey is parked and
later resumed when the business logic is ready. Are you looking for
something like that?

For sure I'm interested to help implementing this behavior for TCP :-)

Thanks!

-- Jeanfrancois


>  
> Thanks a lot,
>  
> Luiz Soares
>
> Flickr agora em português. Você clica, todo mundo vê. Saiba mais
> <http://br.rd.yahoo.com/mail/taglines/flickr/*http://www.flickr.com.br/>.
>

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: Can support async read/write be used outside of Comet?

Luiz Hamilton R L Soares
Jeanfrancois, thanks for your answer.
> Hi Luiz,
>> Hi,

>> 
>> I'm working with Grizzly about two months. It is the core of a LBS
>> Gateway here in Brazil. It is working fine and my code is very
>> simple. I use Controller(), TCPSelectorHandler() classes and a filter, ReadFilter().
>> 
>> Well, now I need to implement an Async Server so I can write to a client
>> without a need to wait for a message. Nowadays I can send a message to a
>> client only after my grizzly server receive a message from the
>> client (My TCP server is working like a UDP server!!).
>> 
>> I'm reading Grizzly ARP source code, but I can't understand how to use
>> it in a TCP Server. There is an example of ARP, but it is for a HTTP
>> server.
> Right.

>> Today I read an answer from Jeanfrancois Arcand in a discuss in this
>> mailing list in 13 Jun 2007 where he was working with the Ericsson team
>> who have requested async write to replace their NIO implementation with
>> Grizzly.
>Right :-) We are still discussing it (was an item on our last meeting,
>which I unfortunately missed).

>> Anyboy know if JFA generalize the implementation so it can be used
>> outside of Comet?
>Can you elaborate exactly on what you are looking at? With Comet, async
>read and write are supported, but also the SelectionKey is parked and
>later resumed when the business logic is ready. Are you looking for
>something like that?
Jeanfrancois, thanks for your answer.
Well, as I've said, I'm working in a LBS (Location Based System). It has
4.000(and growing) cars as clients. They comunicate with my system through a GSM modem/GPRS to
send their location. I can send message to my clients only when they send
a message, because it register for OP_READ and after my ReadFilter implementation
finish reading, I use its SelectionKey to write a message to them.
Now I'm looking at how to trigger an event to send a message to my clients without waiting a message from them.
I've realised that SelectionKey is parked, but I don't know how to "wake it up" and register it to OP_WRITE
without receiving a message from it first.
I managed to do that using HTTP, but I did it just for a test, because my clients use only TCP/IP.
Thanks again,
Luiz

>For sure I'm interested to help implementing this behavior for TCP :-)
>Thanks!
>-- Jeanfrancois

Flickr agora em português. Você clica, todo mundo vê. Saiba mais.

Reply | Threaded
Open this post in threaded view
|

re: Can support async read/write be used outside of Comet?

nomenclature
In reply to this post by Luiz Hamilton R L Soares
Hi Jean-Francois,

I was not yet a member of this mailing list when this conversation
took place, so I've had to do some copying & pasting from the java.net
site. Hopefully this message will be categorized into the correct
message thread.

I am exploring the implementation of a framework on top of Grizzly
that will send messages asynchronously to Flash applications. Since
over 95% of browsers on the web today have Flash installed, this is
similar to Comet but more straightforward on both the server and
client side, and hopefully more performant because of the lack of http
overhead, etc. My dream is to downgrade connections to Comet whenever
Flash is not installed or when a direct non-http socket connection is
blocked by a firewall. I am imagining that I can ultimately scale this
by connecting the server processes to an application server using JMS.

As Luiz mentioned, in
https://grizzly.dev.java.net/servlets/ReadMsg?list=users&msgNo=117 you
wrote:

> The current Comet implementation currently support async read/write via
> a second Selector. I suspect I can generalize the implementation so it
> can be used outside of Comet.

I believe this is correct; the implementation can be generalized. I
really hate the idea of duplicating some of your code and effort in an
attempt to build my framework.

That being said, I am reading through the Comet implementation right
now. Though I'm unfamiliar with Netbeans (grumble grumble), it seems
that the only place in com.sun.grizzly.comet where a Selector is
created is in the CometSelector thread, created and started exactly
once in CometSelector#start. It also seems that CometSelector#start
can only be called once per application, since it seems to only be
called in the CometEngine singleton constructor. I therefore fail to
see the second selector to which you were referring. Or perhaps this
one Selector *is* the second Selector? Maybe the first one was the one
in com.sun.grizzly.http or whatever that handles synchronous http
requests.

Furthermore, there is something about com.sun.grizzly.comet that
surprises me: it seems that the only class in com.sun.grizzly that it
depends on is Pipeline. If you were to generalize the implementation,
how do you imagine pulling the current functionality in CometSelector
into com.sun.grizzly.comet? Suppose I were to go crazy and try to do
this on my own. Are there tests I can run against Grizzly Comet to let
me know if I've inadvertently broken something?

Thank you,
Adam

--
[hidden email]
312-375-9879

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: Can support async read/write be used outside of Comet?

D. J. Hagberg (Sun)
In reply to this post by Luiz Hamilton R L Soares
Luiz Hamilton R L Soares wrote:

> Well, as I've said, I'm working in a LBS (Location Based System). It has
> 4.000(and growing) cars as clients. They comunicate with my system
> through a GSM modem/GPRS to
> send their location. I can send message to my clients only when they send
> a message, because it register for OP_READ and after my ReadFilter
> implementation
> finish reading, I use its SelectionKey to write a message to them.
> Now I'm looking at how to trigger an event to send a message to my
> clients without waiting a message from them.
> I've realised that SelectionKey is parked, but I don't know how to "wake
> it up" and register it to OP_WRITE
> without receiving a message from it first.
> I managed to do that using HTTP, but I did it just for a test, because
> my clients use only TCP/IP.


Here's how I'm doing it for the new Shared Shell (http://sun.com/123)
server, which is similar -- it does binary asynchronous messages over
Grizzly's infrastructure.

My main controller manages a "WriteState" with a queue for outgoing
messages for every SelectionKey in the system (you need to be careful
about mapping anything to SelectionKey because Grizzly could close the
connection on you -- you will need to extend DefaultSelectionKeyHandler
with your own class that overrides cancel(SelectionKey) to be notified
of connections being closed).

So, when a new message generated by the server needs to be
asynchronously written out to the client, here's what happens.

1. The Message object is added to the WriteState's queue

2. The WriteState's registerWriteIntent method is called, which is a
Semaphore-type operation -- if a write task is already pending, this
method returns true and the main controller can return because the data
will (eventually) get written.  If false, we know that we need to
register a Write task and wake up the selector.

3. You need to register OP_WRITE intent with the TCPSelectorHandler by
calling register(SelectionKey,OP_WRITE).  I actually have overridden
this class.  In my version of register(SelectionKey,int), I try to do a
thread-safe race condition check just to make sure a write task has not
already started in the case of OP_WRITE and skipping the
super.register(...) call in that case.  Otherwise I delegate to the
superclass.

4. You'll want to intercept when the Selector actually tells us that
OP_WRITE can be performed.  The easiest way I found to do this was by
overriding TCPSelectorHandler.onWriteInterest(SelectionKey,Context).  My
method looks something like this:

     public boolean onWriteInterest(SelectionKey key, Context ctx) {
         // Look up and set the write-task-imminent flag on my Entry
         // (these are all application-specific controller classes here)
         MyEntry ent = myAppController.flagWriteReady(key);

         // Disable OP_WRITE before doing any other thing
         key.interestOps(key.interestOps() & (~SelectionKey.OP_WRITE));

         // Queue a WriteTask in our app-specific Pipeline.
         myAppController.submitWriteTask(ent);

         // Do *not* delegate to ProtocolChain
         return false;
     }

5. A lot of the heavy lifting is done in my WriteTask, which is managed
in my own *Task pipeline separate from the Read pipeline that is
provided by Grizzly.  I some logic in my pipeline and WorkerThread
around pooling WriteTask objects and exception handling.  The logic each
time the write task is called looks something like this:

. update the WriteState to indicate that a task is running
. write out any SSL-encoded bytes left over from the last time
. SSL-encode any message bytes left over from the last time and
   try to write those out
. keep pulling messages off the write queue until we fill the
   cleartext buffer.  Then SSL-encode all those bytes and try to
   write those out

The WriteState has logic for preserving partial SSL writes or partial
writes of large messages that do not fit within the cleartext (or SSL)
buffer.

Right now, this logic is a bit too tightly-coupled to the rest of the
application to really generalize it for use in GlassFish, but it may
give you some ideas of areas to investigate/explore...

                        -=- D. J.

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: Can support async read/write be used outside of Comet?

Jeanfrancois Arcand-2
In reply to this post by nomenclature
Hi Adam,

sorry for the delay. Today we launched GlassFish v2 and it was kind of
crazy :-)

Adam Duston wrote:

> Hi Jean-Francois,
>
> I was not yet a member of this mailing list when this conversation
> took place, so I've had to do some copying & pasting from the java.net
> site. Hopefully this message will be categorized into the correct
> message thread.
>
> I am exploring the implementation of a framework on top of Grizzly
> that will send messages asynchronously to Flash applications. Since
> over 95% of browsers on the web today have Flash installed, this is
> similar to Comet but more straightforward on both the server and
> client side, and hopefully more performant because of the lack of http
> overhead, etc. My dream is to downgrade connections to Comet whenever
> Flash is not installed or when a direct non-http socket connection is
> blocked by a firewall. I am imagining that I can ultimately scale this
> by connecting the server processes to an application server using JMS.

Yes I can't wait to see your code :-) :-) BTW, with the current Comet
implementation, you can always write your own NotificationHandler that
hooks into a JMS engine (like IBM is doing with Bayeux in WebSpehere).

>
> As Luiz mentioned, in
> https://grizzly.dev.java.net/servlets/ReadMsg?list=users&msgNo=117 you
> wrote:
>
>> The current Comet implementation currently support async read/write via
>> a second Selector. I suspect I can generalize the implementation so it
>> can be used outside of Comet.
>
> I believe this is correct; the implementation can be generalized. I
> really hate the idea of duplicating some of your code and effort in an
> attempt to build my framework.

Yes this is something on my plate. Mostly I want to pull out the Comet
design from HTTP and supports it a the TCP level. I can't promise
exactly when I will have it but for sure it is before end of October
(next week I'm stuck at AjaxWorld, demonstrating the Comet monster :-)).

>
> That being said, I am reading through the Comet implementation right
> now. Though I'm unfamiliar with Netbeans (grumble grumble), it seems
> that the only place in com.sun.grizzly.comet where a Selector is
> created is in the CometSelector thread, created and started exactly
> once in CometSelector#start. It also seems that CometSelector#start
> can only be called once per application, since it seems to only be
> called in the CometEngine singleton constructor. I therefore fail to
> see the second selector to which you were referring.

This is the "main" one where the initial request was accepted. In the
current code, the com.sun.grizzly.http.SelectorThread accept the
requests (under the hood its a TCPSelectorHandler), reads some bytes and
then delegate the bytes request processing to Grizzly Asynchronous
Request Processing (on which Comet is build on top of it, as an
AsyncFilter). Hence the first Selector is the one accepting the connection.

Or perhaps this
> one Selector *is* the second Selector? Maybe the first one was the one
> in com.sun.grizzly.http or whatever that handles synchronous http
> requests.

Indeed.

>
> Furthermore, there is something about com.sun.grizzly.comet that
> surprises me: it seems that the only class in com.sun.grizzly that it
> depends on is Pipeline.

Right, but the current AsyncProcessorTask are http dependent, and that's
the one that sequentially execute the request (with the help of the
AsyncExecutor|AsyncHandler). We need a similar mechanism for TCP where
we can sequentially execute the following operations:

1. Read bytes
2. Parse bytes (request line most of the time)
3. Execute (for Comet/Http, it means hooking the CometEngine)
4. Write response
5. Park or resume the transaction

If you were to generalize the implementation,
> how do you imagine pulling the current functionality in CometSelector
> into com.sun.grizzly.comet?

I would first implement an async mechanism similar to the
AsyncHandler|Executor. Then build Comet on top of it (we shouldn't not
say Comet as it too tight to http). I suspect a generic ProtocolFilter
(maybe named AsyncProtocolFilter) can be the entry point.


Suppose I were to go crazy and try to do
> this on my own. Are there tests I can run against Grizzly Comet to let
> me know if I've inadvertently broken something?

Go crazy anytime :-) Writing Comet unit test is quite complicated and
right now I didn't spend the time on it. But I've several applications
that we can use for testing our implementation. I know this is not the
best way, but that's better than nothing!

Thanks!

-- Jeanfrancois


>
> Thank you,
> Adam
>

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]