Hi Alexey,
Thanks for the reply, I understand more clearly now.
Trying to reverse my use-case back into the GIOP example has muddled
things. In my use case, my filter is always the last in the chain. It
handles the parsing of the messages and also the processing of them,
so I always return StopAction(remainder). I never call
ctx.setMessage() multiple times. The issue for me is that 'remainder'
may contain one or more complete messages which could be processed
immediately, but by returning StopAction(remainder) it means that I am
deferring them until more data is received. This tallies with your
explanation above.
I understand now that returning InvokeAction will cause the remainder
to be processed immediately after this message has finished. So, is it
better to do what I am doing (running a loop over over the inbound
message, parsing as many of my messages as I can, and then returning
StopAction(remainder)) or to simply parse one message and then return
InvokeAction(remainder)? As I understand it, both would have the same
results, but I would expect that greedily looping over the inbound
message would be faster.
I will see if I can pull together a sample later, but hopefully the
above will have helped clarify it anyway.
Thanks,
Sam
On 28 November 2011 09:57, Oleksiy Stashok <oleksiy.stashok_at_oracle.com> wrote:
> Hi Sam,
>
>> Debugging this further I found that the buffer being passed into
>> handleRead(...) was large enough to contain multiple messages. Based
>> upon the sample GIOP code, I see we split the buffer after the first
>> message, the first message is then processed immediately, and we
>> return the remainder for future processing. I had incorrectly assumed
>> that this remainder would be pushed immediately back into the
>> FilterChainContext for processing again. I later realised that this is
>> not the case (for good reason - we'd end up in an infinite loop
>> otherwise), and Grizzly waits for more data before calling
>> handleRead(...) again.
>
> Well, it depends on the NextAction you return from handleRead().
> If you return StopAction(remainder) - then FilterChain processing is going
> to be stopped and wait for more data to come and next time your Filter will
> be called with remainder+new_data Buffer.
> If you return InvokeAction(remainder) - then processing of the current
> message will be passed to the next filter in chain, but once processing of
> the current message is finished - your Filter will be executed with
> remainder message immediately w/o waiting for new data to come.
>
>> Anyway, the result of this is that if handleRead(...) in the example
>> is called with a buffer containing more than one message, then only
>> the first will be processed until some future data arrives (which may
>> never be the case). I fixed this by changing handleRead(...) so that
>> it loops over the buffer, processing multiple messages immediately and
>> leaving at most the remainder of a single message for the future.
>
> Right, I see what you changed, but it will not work :( You can set just one
> message on the context, so if you call context.setMessage(...) several times
> - only last message is getting actually set (it's not a queue).
>
>> Am I barking up the wrong tree, or is this a flaw in the example?
>
> That's good question :)
> I just checked and sample should work fine. If you can share your code
> (which is similar to GIOP), which you said is not working, may be we can
> find something there.
>
> Thanks.
>
> WBR,
> Alexey.
>
>