[logback-dev] Question: AsyncAppender's thread safety?
Ceki Gulcu
ceki at qos.ch
Thu Mar 3 11:13:51 UTC 2016
Hi again,
Would you please create a JIRA issue for the problem you raised on the
mailing list?
--
Ceki
On 3/3/2016 9:16, Ceki Gulcu wrote:
> Hi Aaron,
>
> Comments inline.
>
> On 3/2/2016 23:40, Aaron Curley wrote:
>
> > Hello all,
> >
> > I’m most likely missing something here, but reviewing AsyncAppender in
> > logback classic 1.1.6, I’m not sure how it’s entirely thread safe,
> > especially with respect to the “started” flag in its grandparent
> > class (UnsynchronizedAppenderBase).
> >
> > In particular, the doAppend() method in UnsynchronizedAppenderBase
> > checks the “started” boolean member's value (line 72) before
> > actually appending, yet, no synchronization primitives are (or appear
> > to be, from my perspective) used to ensure that the “started”
> > member is visible to all threads once it is updated via start(). I
> > would have thought that AsyncAppender would have inherited from
> > AppenderBase (which is thread safe and does mark “started” as
> > volatile) rather than extending UnsynchronizedAppenderBase. Baring
> > this, I would have thought that the “started” member would be
> > “overridden” with AsyncAppender’s own volatile version of this
> > flag or access to started would be protected with a lock.
> >
> > As a result, isn’t it possible that if one thread calls start() and
> > then another thread immediately logs something (calling doAppend()),
> > the logging thread would see “started” as false? Wouldn’t this
> > result in “skipping” certain log messages entirely (if the
> > appender was very recently started)?
>
> You are absolutely right. Events generated in other threads could be
> lost until the new value (true) of start was propagated to those
> threads. Good catch.
>
> > I think I must be missing something. Can someone clarify how this
> > works? Thanks in advance!
> >
> > Best Regards,
> >
> > Aaron Curley
> > accwebs at gmail.com
> >
> > P. S. I would have also expected start() and stop() (in
> > AsyncAppender or its parent) to be overridden to introduce
> > synchronization, since AsyncAppender is generally used by multiple
> > threads. Right now, it appears that start & stop operations are not
> > idempotent nor are multiple (simultaneous) calls prevented.
>
> The idempotency could be enforced by introducing a check if(isStarted())
> {return;} at the top of the start() method. But again, good catch.
>
> Here are a couple of questions for you.
>
> 1) How would you write a test case for asserting the correct propagation
> of start?
> 2) What would be the computational cost of having a volatile start?
> 3) What would you suggest to minimize the cost if the cost was elevated?
>
> Best regards,
>
> --
> Ceki
>
> _______________________________________________
> logback-dev mailing list
> logback-dev at qos.ch
> http://mailman.qos.ch/mailman/listinfo/logback-dev
More information about the logback-dev
mailing list