dev@grizzly.java.net

some useful discussion on Grizzly controller/ client side

From: Harsha Godugu <Harsha.Godugu_at_Sun.COM>
Date: Tue, 21 Aug 2007 17:29:02 -0700

>>Thanks a lot Ken. Actually, if I take off the scenario that I need to
>>write during parsing bytes,
>>my code /work becomes much simpler. I do not need to pass the
>>connection/channel arg
>>to the parser methods as it is now in the MessageBase.java. Thanks
>>Charlie for your idea to on
>>the separation of parsing to processing. But, even then, how do I let
>>the ORB worker know that,
>>its time to write to the channel. I understand that, any channel is
>>always ready to write, unless
>>otherwise we set the Op bit of the selector to just OP_READ alone.
>>
>>

> You will need to have a protocol-level representation of the channel (our
> current SocketOrChannelConnectionImpl) to handle this. Basically what
> you need is
> writeLock. The problem is that any thread may at any time decide to
> write to any connection (at least as far as the transport is concerned),
> so the transport cannot help us to avoid problems. Every time an ORB
> worker thread wants to write, it needs to:
>
> 1. Acquire the write lock
> 2. write to the connection (which delegates to the Grizzly write
> method, which handles temp. selectors, SSL, etc. as needed)
> 3. release the write lock
>
> That way we don't have two different threads simultaneously writing to
> the same connection.


The problem right now is, access to the channel on the client side and
the server side, and making it to
go through the selector. That means, upon parsing of bytes, if there is
a need to write to the channel,
let us assume that, we delegate writing to the ORB worker thread. Now,
carefully analyse how we implement
with Grizzly's present code. In order to do this writing, first the
worker thread needs to get informed by the
TCPSelectorHandler that, the underlying channel (that the worker thread
somehow got access to?)
is READY to write. How do we do this?


>>
>> Note that the connections cache get/release mechanism is NOT
>> sufficient. The outbound
>> connection cache will try to give different get requests for the same
>> endpoint different connections,
>> but it can't always do that. When two get calls that have not yet
>> been released both get the
>> same connection, write lock is essential to avoid problems like write
>> calls that are interleaved
>> within the same GIOP message.
>>
>> The inbound connection cache is basically the same: we could have
>> multiple worker
>> threads all competing to write a response to the same accepted
>> connection in the inbound
>> cache. That's why we have essentially the same mechanism on both
>> sides today.
>>
>
>
>>>>On the other hand, I'm using the same tcpSelectorHandler both on client
>>>>and server side by overriding the
>>>>grizzly's TcpSelectorHandler at many places. I want to know all your
>>>>thoughts on this too.
>>>>Basically, I wanted to use only one type of connector on both client
>>>>and serverside.
>>>>
>>
>>
>> I'm always in favor of using only one of something whenever possible.
>> But I'm not sure
>> of all of the Grizzly details here. It seems like the server pipeline
>> can fairly easily be
>> plugged into the TCPConnectorHandlers, as Jean-Francois pointed out
>> earlier.
>> Is that not enough? Are there other issues here?
>
>

The issue is about access to the underlying channel. On serverside it's
different it's just a nio channel.
On client side it's TcpConnector.

Take the following scenario:

On serverside:
            upon accept, Grizzly does gets the socketchannel from the
TcpSelectorHandler. ( whose selector
is registered with OP_ACCEPT events for the serversocket /acceptor. Upon
accept, what it gets is an NIO socket
channel. This SHOULD be changed to TcpConnector in Grizzly.

On client side:
               onConnect() we get socketchannel and set it inside
tcpConnector.

I hope this helps with clarity.

thanks..