users@grizzly.java.net

Re: Need help implementing ProtocolParser

From: Erik Svensson <erik.svensson_at_six.se>
Date: Mon, 17 Mar 2008 13:10:33 +0100

Howdy!

(note: I'm at work and can't look too close to the code right now)

A quick look at the code shows that, as far as Grizzly knows, you aren't
doing anything with the incoming byteBuffer. The position is the same when
releaseBuffer() is called as it was when startBuffer() was called.
Even more important, the buffer is still unread and full when you exit
releaseBuffer()! I'm not the one to answer what happens when the buffer
associated is (still) full when reading from the socket but try
adding a byteBuffer.clear() before exiting releaseBuffer().

Looking at the code I'm wondering a bit about how you handle your retain
buffer. If I was implementing this (with the scant knowledge I have) I would
append the incoming bytebuffer to the retain buffer and then parse the
retain buffer. ie:

  ByteBuffer byteBuffer, incomingPacketBuffer;


  incomingPacketBuffer = ByteBuffer.allocate(some_size);


  public void startBuffer(ByteBuffer pBuf) {
    if (incomingPacketBuffer.remaining() < pBuf) {
      // grow incomingPacketBuffer, by creating a new one and copy the old
into the new.
    }
    incomingPacketBuffer.position(incomingPacketBuffer.limit());
    incomingPacketBuffer.put(pBuf);
    incomingPacketBuffer.position(0); // position at the begining
  }

It seems to me that you are reading from the incoming buffer before you are
checking to see if there is anything remaining in the incomingPacketBuffer.
If you get an incomplete message shouldn't incomingPacketBuffer be the
buffer that contains the header (and maybe more) for the message?

HTH

cheers
/Erik

> public boolean releaseBuffer() {
> byteBuffer = null;
> currentPosition = 0;
> return isExpectingMoreData;
> } //releaseBuffer
> }
>
> When a big packet is about to arrive `byteBuffer` contains only 8k of data
> (as it should according to grizly's implementation) - so i copy data into
> incomingPacketBuffer and
> set `isExpectingMoreData = true;`. The problem: instance that handled this
> `byteBuffer` is not called for the second time! insted grizzly creates a new
> instance of `A1ProtocolParser` through my own `ProtocolChainInstanceHandler`
>
> controller.setProtocolChainInstanceHandler(new
> DefaultProtocolChainInstanceHandler() {
>
> private final A1ParserProtocolFilter a1ParserProtocolFilter = new
> A1ParserProtocolFilter();
> private final ProtocolFilter echoFilter = new ProtocolFilter() {
>
> public boolean execute(Context ctx) throws IOException {
> System.out.println(
> new
> String(((IncomingPacket)ctx.getAttribute(ProtocolParser.MESSAGE)).data,
> "UTF-8")
> );
> ctx.removeAttribute(ProtocolParser.MESSAGE);
> return false;
> }
>
> public boolean postExecute(Context ctx) throws IOException {
> return true;
> }
> };
>
> @Override
> public ProtocolChain poll() {
> ProtocolChain protocolChainX = protocolChains.poll();
> if (protocolChainX == null) {
> DefaultProtocolChain defaultProtocolChain = new
> DefaultProtocolChain();
> defaultProtocolChain.setContinuousExecution(true);
> defaultProtocolChain.addFilter(a1ParserProtocolFilter);
> defaultProtocolChain.addFilter(echoFilter);
> protocolChainX = defaultProtocolChain;
> offer(protocolChainX);
> }
> return protocolChainX;
> }
> });
>
> The second question: line `offer(protocolChainX);` according to this post
> (http://www.nabble.com/DefaultProtocolChainInstanceHandler-td15412709.html)
> should exist, but it do not exist in the last (668 by now) revision of this
> file
> https://grizzly.dev.java.net/source/browse/grizzly/trunk/modules/grizzly/src/t
> est/java/com/sun/grizzly/ProtocolParserTest.java?rev=668&view=log
> is this a bug in a test unit? by the way it don't exist in many blog posts
> and samples i've seen.
>
> p.s. sorry for my english-i'm from Russia :)