Hello Erik,
>>
>> seems currently we have bug in Grizzly, which doesn't let you to rely
>> on fact, that the same ProtocolParser will be called, when next
>> request bytes will come.
>> Can you please file the bug on this?
>
> If nobody else does it, I'll do it tonight.
Thank you in advance!
>
>
>> As workaround, I can propose you to not keep retain_buffer in your
>> ProtocolParser.
>> This change will make your ProtocolParser stateless, and not depend
>> on
>> fact, that same instance will be called for next request on the same
>> channel.
>>
>> The idea is to use just single buffer (saved). Please take a look at
>> code bellow. I didn't test it, as don't have your testcase, but you
>> can see the idea there.
>
> In other words you move the state into the byte buffer associated
> with the
> the current thread.
Correct. We can not guarantee that ProtocolFilter will be the same,
but ByteBuffer will be.
Also, hope, solution with just single buffer can perform faster, as
less copy operations will be executed :)
>
>
>> If you will need more help - please send your complete testcase code,
>> so I'll be able to run it.
>
> I'll test it out with my code. If the currentThread is the same
> thread that
> receives the next read from the relevant socket it will work.
Hope so :)
Thanks.
WBR,
Alexey.
>
>
> cheers
>
> /Erik
>
>> Thanks.
>>
>> WBR,
>> Alexey.
>>
>> public class ProtocolParser implements
>> com.sun.grizzly.ProtocolParser<SimpleMessage> {
>>
>> private ByteBuffer saved;
>> private int position;
>> private int limit;
>> private SimpleMessage mess;
>> private boolean wants_more_data = false;
>> private boolean has_unparsed_data = false;
>>
>> public ProtocolParser() {
>> }
>>
>> public boolean isExpectingMoreData() {
>> System.out.println("isExpectingMoreData : " +
>> wants_more_data);
>> return wants_more_data;
>> }
>>
>> public boolean hasMoreBytesToParse() {
>> return has_unparsed_data;
>> }
>>
>> public SimpleMessage getNextMessage() {
>> // the call pattern should be:
>> // hasNextMessage() == true
>> // getNextMessage()
>> // but if not:
>> if (null == mess) {
>> mess = extractMessage();
>> }
>> SimpleMessage tmp = mess;
>> mess = null;
>>
>> return tmp;
>> }
>>
>> public boolean hasNextMessage() {
>>
>> if (null == mess) {
>> mess = extractMessage();
>> }
>>
>> return (mess != null);
>> }
>>
>> public void startBuffer(ByteBuffer bb) {
>> saved = bb;
>> saved.flip(); // flip the byte buffer for reading. (should
>> have been done already)
>> }
>>
>> public boolean releaseBuffer() {
>> System.out.println("releaseBuffer : ");
>> if (wants_more_data) {
>> System.out.println("releaseBuffer : Doing compact");
>> // If saved buffer is full and still need to read more
>> data
>> if (saved.remaining() == saved.capacity()) {
>> reallocateSaved();
>> }
>> } else {
>> saved.clear();
>> }
>> return wants_more_data;
>> }
>>
>> private void reallocateSaved() {
>> ByteBuffer tmpBuffer =
>> ByteBufferFactory.allocateView(saved.capacity() * 2, false);
>> tmpBuffer.put(saved);
>> saved = tmpBuffer;
>> ((WorkerThread) Thread.currentThread()).setByteBuffer(saved);
>> }
>>
>> private SimpleMessage extractMessage() {
>> SimpleMessage message = null;
>>
>> if (!saved.hasRemaining()) {
>> // there are no more readable bytes in the buffer
>> // this should mean that we've read all messages in the
>> buffer
>> wants_more_data = false;
>> has_unparsed_data = false;
>> saved.clear(); // clean up our byte buffer. No one else
>> will do it for us
>> return message;
>> }
>>
>> // save the position before we send it off to the parser
>> position = saved.position();
>> message = SimpleMessage.parse(saved);
>> System.out.println("parsed message is null ? " + (message ==
>> null ? "YES"
>> : "NO"));
>> if (message == null) {
>> // not enough bytes for a message
>> // but we know there are bytes so there must be
>> // an incomplete message there
>> saved.position(position);
>> wants_more_data = true;
>> has_unparsed_data = false;
>> } else {
>> wants_more_data = false;
>> has_unparsed_data = saved.hasRemaining();
>> if (has_unparsed_data) {
>> saved.compact();
>> saved.flip();
>> } else {
>> saved.clear();
>> }
>> }
>> return message;
>> }
>>
>>
>> On Mar 18, 2008, at 10:57 , Erik Svensson wrote:
>>
>>> Howdy all!
>>>
>>> I've implemented a protocol parser using Ash2K:s case as a template
>>> and I
>>> get the same result. I send a message of somehting like 15k bytes.
>>> I save the buffer, return wants_more_data = true and I expect the
>>> same
>>> parser to be called again but instead a new one is created and so I
>>> lose my
>>> saved buffer.
>>>
>>> Running 1.7.2 with the debugger I notice that the return value from
>>> releaseBuffer() is ignored.
>>>
>>> Here's my protocol parser:
>>>
>>>
>>> public class ProtocolParser implements
>>> com.sun.grizzly.ProtocolParser<SimpleMessage> {
>>>
>>> private ByteBuffer saved,retain_buffer;
>>> private int position;
>>> private int limit;
>>> private SimpleMessage mess;
>>> private boolean wants_more_data = false;
>>> private boolean has_unparsed_data = false;
>>>
>>> public ProtocolParser() {
>>> System.out.println("Creating a new ProtocolParser");
>>> retain_buffer = ByteBuffer.allocateDirect(18000);
>>> }
>>>
>>> public boolean isExpectingMoreData() {
>>> System.out.println("isExpectingMoreData : "+wants_more_data);
>>> return wants_more_data;
>>> }
>>>
>>> public boolean hasMoreBytesToParse() {
>>> return has_unparsed_data;
>>> }
>>>
>>> public SimpleMessage getNextMessage() {
>>> // the call pattern should be:
>>> // hasNextMessage() == true
>>> // getNextMessage()
>>> // but if not:
>>> if (null == mess) {
>>> mess = extractMessage();
>>> }
>>> SimpleMessage tmp = mess;
>>> mess = null;
>>>
>>> return tmp;
>>> }
>>>
>>> public boolean hasNextMessage() {
>>>
>>> if (null == mess) {
>>> mess = extractMessage();
>>> }
>>>
>>> return ( mess != null);
>>> }
>>>
>>> public void startBuffer(ByteBuffer bb) {
>>> saved = bb;
>>> saved.flip(); // flip the byte buffer for reading. (should have
>>> been
>>> done already)
>>>
>>> if ((saved.remaining() > retain_buffer.remaining())) {
>>> // grow the retain buffer...
>>> System.out.println("Grow retain buffer not implemented");
>>> return;
>>> }
>>> retain_buffer.put(saved);
>>> retain_buffer.flip();
>>> bb.clear();
>>> }
>>>
>>> public boolean releaseBuffer() {
>>> System.out.println("releaseBuffer : ");
>>> if (wants_more_data) {
>>> System.out.println("releaseBuffer : Doing compact");
>>> retain_buffer.compact();
>>> } else {
>>> retain_buffer.clear();
>>> }
>>> return wants_more_data;
>>> }
>>>
>>> private SimpleMessage extractMessage() {
>>> SimpleMessage message = null;
>>>
>>> if (!retain_buffer.hasRemaining()) {
>>> // there are no more readable bytes in the buffer
>>> // this should mean that we've read all messages in the buffer
>>> wants_more_data = false;
>>> has_unparsed_data = false;
>>> saved.clear(); // clean up our byte buffer. No one else will do
>>> it for
>>> us
>>> return message;
>>> }
>>> // save the position before we send it off to the parser
>>> position = retain_buffer.position();
>>> message = SimpleMessage.parse(retain_buffer);
>>> System.out.println("parsed message is null ? "+(message == null ?
>>> "YES"
>>> : "NO"));
>>> if (message == null) {
>>> // not enough bytes for a message
>>> // but we know there are bytes so there must be
>>> // an incomplete message there
>>> if (retain_buffer.position() != position) {
>>> retain_buffer.position(position);
>>> }
>>> wants_more_data = true;
>>> has_unparsed_data = false;
>>> } else {
>>> // here we have a complete message
>>> if (retain_buffer.limit() == retain_buffer.position()) {
>>> // the end of the buffer is reached.
>>> wants_more_data = false;
>>> has_unparsed_data = false;
>>> } else {
>>> has_unparsed_data = true;
>>> // here we can't accuratly set wants_more_data.
>>> // since we don't know if the bytes in the buffer is a
>>> // complete message or not
>>> }
>>> }
>>> return message;
>>> }
>>> }
>>>
>>> cheers
>>> /Erik
>>>
>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: users-unsubscribe_at_grizzly.dev.java.net
>>> For additional commands, e-mail: users-help_at_grizzly.dev.java.net
>>>
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe_at_grizzly.dev.java.net
>> For additional commands, e-mail: users-help_at_grizzly.dev.java.net
>>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_grizzly.dev.java.net
> For additional commands, e-mail: users-help_at_grizzly.dev.java.net
>