Hi,

Have you considered that the part taking a long time inside the
IOUtils.copy method might be the reading from the socket InputStream ?
Because if so, then it would be incorrect to blame poor performance on the
LoggingInterceptor : reading from the stream is something that is to be
done anyway. The fact that the logger is the one to do it makes it "take
the blame", but something somewhere is gonna need to pay this price anyway.

So, you may have already taken that into account, but if not, I suggest you
dig a bit deeper. And if your profiler is telling you that the logging is
slow, who is accountable for that : 1) the reading part from the input ? 2)
the writing part from the output ? 3) actually both ?

1) would mean : making anything async is of no use, if not the logger, then
something else will have to pay the exact same "price" for reading (i.e.
the unmarshaller)
2) seems unlikely to me, we are writing in memory, so it should be really
fast

Anyway, about your primary question : for different purposes (messages
persistence to disk) we had to build a variant of the LoggingInterceptor.
It's not that hard, and you can actually achieve async behaviour by
following a pattern such as that of the TeeInputStream / TeeReader (see
apache commons). The building blocks are :
1) Just as the logger does in the code you have extracted, grab hold of the
original InputStream
2) Decorate it with a new implementation, that, each time a read method is
called, dispatches (asynchronously if you want) a write of the read content
(be carreful of not sharing / reusing the same read and write buffers !)
3) Put this decorated stream back into the message
4) Register interceptors to close the decorated stream further down the
interceptor path
5) Repeat for InputStream and Readers, because some implementations, e.g.
SOAP/JMS based on TextMessages are not Stream based but reader based.

It's not that hard, but I do not know of any existing interceptor that work
that way. Here, we've had a working version in production for quiet some
time, but never found it to be slow / time consuming (and we did extensive
load testing). The fact is : our RAM buffers and disks are faster than our
network, so the copying time is actually a none issue, dwarfed by the
network + actual service call time.



2016-02-29 14:22 GMT+01:00 rohandm <[email protected]>:

> We are currently using LoggingInInterceptor/LoggingOutInterceptor to log
> soap
> messages in our application however these interceptors takes a significant
> amount of time especially on the IOUtils.copy(is, bos)  call. Is their any
> way to call this part of the code in a separate thread without having the
> InputStream closed on us or Are there any other alternatives to improve
> performance here?
>
>
> InputStream is = message.getContent(InputStream.class);
>         if (is != null) {
>             CachedOutputStream bos = new CachedOutputStream();
>             try {
>                 IOUtils.copy(is, bos);
>
>                 bos.flush();
>                 is.close();
>
>                 message.setContent(InputStream.class,
> bos.getInputStream());
>                 if (bos.getTempFile() != null) {
>                     //large thing on disk...
>                     buffer.getMessage().append("\nMessage (saved to tmp
> file):\n");
>                     buffer.getMessage().append("Filename: " +
> bos.getTempFile().getAbsolutePath() + "\n");
>                 }
>                 if (bos.size() > limit) {
>                     buffer.getMessage().append("(message truncated to " +
> limit + " bytes)\n");
>                 }
>                 writePayload(buffer.getPayload(), bos, encoding, ct);
>
>                 bos.close();
>             } catch (Exception e) {
>                 throw new Fault(e);
>             }
>         }
>         log(buffer.toString());
>
>
>
>
> --
> View this message in context:
> http://cxf.547215.n5.nabble.com/LoggingInInterceptor-consuming-time-for-big-messages-tp5766419.html
> Sent from the cxf-user mailing list archive at Nabble.com.
>

Reply via email to