users@grizzly.java.net

Re: Grizzly 2.0 filter chains and client side implementations

From: Oleksiy Stashok <Oleksiy.Stashok_at_Sun.COM>
Date: Wed, 20 May 2009 19:00:13 +0200

Hi,

>
> Can you explain more about Filter and Codec? I saw the codec and I
> don't
> quite understand the necessity of it either.
No problem :)

Assume we have following FilterChain.

         TCPNIOTransport transport =
TransportFactory.getInstance().createTCPTransport();
         transport.getFilterChain().add(new TransportFilter());
         transport.getFilterChain().add(new SSLFilter()); // SSL
Decode/encode
         transport.getFilterChain().add(new HttpFilter()); //
Buffer<->HttpRequest/Response decoding/encoding
         transport.getFilterChain().add(new HttpProcess()); //
Process HttpRequest/Response

this FilterChain implements Https protocol, right (HTTP over SSL).

Let's say we have client connection:

             Future<Connection> future =
transport.connect("localhost", PORT);
             TCPNIOConnection connection = (TCPNIOConnection)
future.get(10, TimeUnit.SECONDS);

and we want to send HttpRequest on the connection (HttpFilter knows
how to encode/decode HttpMessage to/from Buffer).

One option is to enable IOEvent.WRITE on connection:
connection.enableIOEvent(IOEvent.WRITE);

and send HttpRequest using FilterChain (handleWrite() will be called
on each FilterChain Filter).


Or other way to do that - is use Codec:

   HttpRequest httpRequest = new HttpRequest(....);
   .... prepare HttpRequest ......
   Transformer transformer =
transport.getFilterChain().getCodec().getEncoder();
   Buffer buffer = (Buffer) transformer.encode(connection,
httpRequest, null);
   connection.getWriter().writeBuffer(buffer);
   connection.getWriter().flush();

In this example I just took FilterChain Codec, which will pass all
filters in filter chain one by one, and if Filter implements Codec -
ask it to transform source message.
So HttpRequest will be passed to HttpFilter, which will transform it
to Buffer, then SSLFilter will encode the Buffer with SSL. So finally
I'll get Buffer, which could be sent to network.


But as I told, I see Codecs useful mostly for client side applications
get more clear code. For server side - we recommend to use FilterChain.

Hope this will help.

WBR,
Alexey.

>
>
>
>
> Oleksiy Stashok wrote:
>>
>>
>>> Ahh... Now it all makes sense. I saw all the codec related code in
>>> the repo but don’t see how they can be used. This should work for
>>> the client side and I like the message abstraction since we do that
>>> now anyways. I guess the encode transform calls the filters from
>>> last to first and the decode from first to last?
>> Right.
>>
>>> What will the decode side look like?
>> Decode will work similar way as encoding. You'll be able to use it in
>> standalone (without FilterChain) mode, though I'd still suggest to
>> use
>> FilterChain, if possible.
>>
>>> Is the codec API designed as a replacement to the filter /
>>> handleRead/Write methods of implementing custom protocols?
>> It's not replacement. I think FilterChain API fits better for server
>> side needs and easier in implementation.
>> Codec API could be interesting for client side and sometimes useful
>> in
>> server side scenarios (like scenario you have with sending messages).
>>
>>> How do you think it will affect performance and memory use?
>> It's exactly the reason, why I think FilterChain is better. All the
>> transport/memory related operations are hidden from developer and
>> there is less chance for something to be broken. In FilterChain
>> Filter
>> you get access to StreamReader/Writer, which cares about allocating/
>> releasing memory etc. FilterChain is always executed in WorkerThread,
>> using which we can optimize memory allocation, object creation etc.
>> With Codec - you never know in which type of thread it is executed,
>> you have to control buffers..
>>
>> So, I'd still advice to use FilterChain as primary approach.
>>
>>> Grizzly 2.0 is getting very interesting and I can’t wait to see the
>>> next set of changes!
>> Thank you for the feedback! :)
>>
>> WBR,
>> Alexey.
>>
>>>
>>>
>>> Thanks again
>>> Bo
>>>
>>>
>>> On 5/19/09 3:01 PM, "Oleksiy Stashok" <Oleksiy.Stashok_at_Sun.COM>
>>> wrote:
>>>
>>>> Hi Bo,
>>>>
>>>> looks like you're looking for Codec API to be supported by
>>>> FilterChain (FilterChain.getCodec()).
>>>> We have that API, but it's not implemented for FilterChain. I'll
>>>> complete the implementation nearest time.
>>>>
>>>> It will work like:
>>>>
>>>> Buffer buffer =
>>>> filterChain.getCodec().getEncoder().transform(message);
>>>> connection.getStreamWriter().writeBuffer(buffer);
>>>>
>>>> This way, tranform will sequentially call each Filter, which
>>>> implement FilterCodec interface, to encode the message.
>>>>
>>>> Does this sound good for you?
>>>>
>>>> WBR,
>>>> Alexey.
>>>>
>>>>>
>>>>> I have a question about the design of client side code, or any non
>>>>> IO event
>>>>> driven code, using Grizzly 2.0. I understand that processing is
>>>>> triggered on
>>>>> IO events and each filter in the filter chain will handle the
>>>>> event
>>>>> accordingly. This works well in a server-side request-response
>>>>> protocol
>>>>> model. The protocol parser can just read and write to the
>>>>> StreamReader and
>>>>> StreamWriters from the FilterChainContext without having knowledge
>>>>> of
>>>>> previous filters on the chain.
>>>>>
>>>>> However, what I don't see is how to do the same on the client side
>>>>> or if the
>>>>> server needs to send unsolicited messages to the client. In these
>>>>> cases,
>>>>> there are no IO events to trigger the filter chain but the
>>>>> protocol message
>>>>> still needs to be handled by the filters before going out the
>>>>> wire. I
>>>>> understand for SSLFilter I can just wrap the SSLStreamWriter
>>>>> around
>>>>> StreamWriter from the TCPConnection but then my protocol parser
>>>>> code will
>>>>> need to know about the previous filters on the chain and their
>>>>> implementation. If I change the filters in the chain I will also
>>>>> need to
>>>>> change the wrappings of StreamWriters and StreamReaders.
>>>>>
>>>>> Is there a easier way to do this? I envision a two-way filter
>>>>> chain where I
>>>>> just write to "protocol" side of the chain and previous filters
>>>>> will process
>>>>> the write request before sending it out the wire.
>>>>>
>>>>> Thanks again
>>>>> Bo
>>>>>
>>>>>
>>>>>
>>>>> ---------------------------------------------------------------------
>>>>> To unsubscribe, e-mail: users-unsubscribe_at_grizzly.dev.java.net
>>>>> For additional commands, e-mail: users-help_at_grizzly.dev.java.net
>>>>>
>>>>
>>>>
>>
>>
>>
>
> --
> View this message in context: http://www.nabble.com/Grizzly-2.0-filter-chains-and-client-side-implementations-tp23615467p23638117.html
> Sent from the Grizzly - Users mailing list archive at Nabble.com.
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_grizzly.dev.java.net
> For additional commands, e-mail: users-help_at_grizzly.dev.java.net
>