You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@mina.apache.org by Johan Haleby <ha...@gmail.com> on 2008/05/27 21:47:23 UTC
Continuous XML stream protocol decoder implementation
Hi,
I'm using Apache Mina to parse continuous XML streams. I.e. a client
connects to Mina and holds a connection for its entire life-cycle.
During this time the client may send and receive a lot of (small) XML
messages. I wonder how I should implement this is in a good way? Right
now my protocol decoder is a singleton that make use of cached thread
pool because each client creates a new custom made inputstream
implementation that is read in a separate thread by XStream. When new
data arrives to the decode method it just pushes this data to the
inputstream. The inputstream itself uses a blocking queue, so the read
method waits until it has data or that an "end of stream marker" has
been found, e.g. until </request> has been found. I'm letting XStream
(configured with XPP3) take care of marshalling the data in the XML
inputstream in this other thread. So whenever XStream has found the "end
of stream marker" and created a new object from the data in the
inputstream it calls the ProtocolDecoderOutput.write(..) with that
object. The inputstream implementation is then "reset" so that it
accepts additional data. I have my worries that this may not be optimal,
especially since I "create a new thread" (well I'm using the cached
thread pool) for XStream for each connection in the ProtocolDecoder. So
how could I improve on this? (Comments on the XML parsing technique are
also welcome).
Thanks
Johan
Re: Continuous XML stream protocol decoder implementation
Posted by Alex Karasulu <ak...@apache.org>.
Hi Johan,
On Tue, May 27, 2008 at 6:44 PM, Johan Haleby <ha...@gmail.com> wrote:
> Alex Karasulu wrote:
>
>> Hi Johan,
>>
>> On Tue, May 27, 2008 at 3:47 PM, Johan Haleby <ha...@gmail.com> wrote:
>>
>>
>>
>>> Hi,
>>>
>>> I'm using Apache Mina to parse continuous XML streams. I.e. a client
>>> connects to Mina and holds a connection for its entire life-cycle. During
>>> this time the client may send and receive a lot of (small) XML messages.
>>> I
>>> wonder how I should implement this is in a good way? Right now my
>>> protocol
>>> decoder is a singleton that make use of cached thread pool because each
>>> client creates a new custom made inputstream implementation that is read
>>> in
>>> a separate thread by XStream. When new data arrives to the decode method
>>> it
>>> just pushes this data to the inputstream. The inputstream itself uses a
>>> blocking queue, so the read method waits until it has data or that an
>>> "end
>>> of stream marker" has been found, e.g. until </request> has been found.
>>>
>>>
>>
>>
>> I presume the read from the InputStream is using threads from this shared
>> thread pool? This is a tough problem to deal with when you have some
>> blocking IO primitives between MINA and your application.
>>
>>
> First of all thanks for your reply, and yes the inputstream is of course
> using threads from the shared thread-pool.
>
>> Although not optimal, I would use a decoder per session and start
>> collecting
>> a request buffer in the MINA session until you detect the completion of a
>> request. This way there is minimal processing except for request
>> termination detection. Also you don't have to have this thread cache
>> (pool)
>> to contend with in a singleton. When you detect the arrival of a complete
>> request you can trigger XStream deserialization of the buffer to produce
>> the
>> object and forward the object up to higher layers.
>>
>> HTH,
>> Alex
>>
>>
> This is exactly what I was thinking as an alternative. And since the XML
> messages are small I don't really need to worry too much about the cost of
> double data holding which will occur in this case.
Right you're not going to pay as much for the extra memory for kinda double
buffering the request as much as you'll pay for holding up threads and
context switching.
Really what would be the best case would be to have asynchronous XML
processing where the parser can pause while maintaining state then start
when more data is available. But this should work well for you.
> I just have one follow-up question, how do you configure Mina to use one
> ProtocolDecoder instance per session?
>
Sure np. You can implement a ProtocolCodecFactory to instantiate encoders
and decoders for each session on creation events. You can use that without
any extra code in conjunction with a ProtocolCodeFilter which you just add
to your filter chain.
Good luck,
Alex
Re: Continuous XML stream protocol decoder implementation
Posted by Johan Haleby <ha...@gmail.com>.
Alex Karasulu wrote:
> Hi Johan,
>
> On Tue, May 27, 2008 at 3:47 PM, Johan Haleby <ha...@gmail.com> wrote:
>
>
>> Hi,
>>
>> I'm using Apache Mina to parse continuous XML streams. I.e. a client
>> connects to Mina and holds a connection for its entire life-cycle. During
>> this time the client may send and receive a lot of (small) XML messages. I
>> wonder how I should implement this is in a good way? Right now my protocol
>> decoder is a singleton that make use of cached thread pool because each
>> client creates a new custom made inputstream implementation that is read in
>> a separate thread by XStream. When new data arrives to the decode method it
>> just pushes this data to the inputstream. The inputstream itself uses a
>> blocking queue, so the read method waits until it has data or that an "end
>> of stream marker" has been found, e.g. until </request> has been found.
>>
>
>
> I presume the read from the InputStream is using threads from this shared
> thread pool? This is a tough problem to deal with when you have some
> blocking IO primitives between MINA and your application.
>
First of all thanks for your reply, and yes the inputstream is of course
using threads from the shared thread-pool.
> Although not optimal, I would use a decoder per session and start collecting
> a request buffer in the MINA session until you detect the completion of a
> request. This way there is minimal processing except for request
> termination detection. Also you don't have to have this thread cache (pool)
> to contend with in a singleton. When you detect the arrival of a complete
> request you can trigger XStream deserialization of the buffer to produce the
> object and forward the object up to higher layers.
>
> HTH,
> Alex
>
This is exactly what I was thinking as an alternative. And since the XML
messages are small I don't really need to worry too much about the cost
of double data holding which will occur in this case. I just have one
follow-up question, how do you configure Mina to use one ProtocolDecoder
instance per session?
/Johan
Re: Continuous XML stream protocol decoder implementation
Posted by Alex Karasulu <ak...@apache.org>.
Hi Johan,
On Tue, May 27, 2008 at 3:47 PM, Johan Haleby <ha...@gmail.com> wrote:
> Hi,
>
> I'm using Apache Mina to parse continuous XML streams. I.e. a client
> connects to Mina and holds a connection for its entire life-cycle. During
> this time the client may send and receive a lot of (small) XML messages. I
> wonder how I should implement this is in a good way? Right now my protocol
> decoder is a singleton that make use of cached thread pool because each
> client creates a new custom made inputstream implementation that is read in
> a separate thread by XStream. When new data arrives to the decode method it
> just pushes this data to the inputstream. The inputstream itself uses a
> blocking queue, so the read method waits until it has data or that an "end
> of stream marker" has been found, e.g. until </request> has been found.
I presume the read from the InputStream is using threads from this shared
thread pool? This is a tough problem to deal with when you have some
blocking IO primitives between MINA and your application.
Although not optimal, I would use a decoder per session and start collecting
a request buffer in the MINA session until you detect the completion of a
request. This way there is minimal processing except for request
termination detection. Also you don't have to have this thread cache (pool)
to contend with in a singleton. When you detect the arrival of a complete
request you can trigger XStream deserialization of the buffer to produce the
object and forward the object up to higher layers.
HTH,
Alex