https://issues.apache.org/jira/browse/LOG4J2-859
On 24 September 2014 21:07, Gary Gregory <garydgreg...@gmail.com> wrote: > Revisit for 2.2... > > Gary > > On Wed, Sep 24, 2014 at 9:59 PM, Matt Sicker <boa...@gmail.com> wrote: > >> Reverted the commit. >> >> On 24 September 2014 14:30, Matt Sicker <boa...@gmail.com> wrote: >> >>> I'll move it to a branch tonight, sorry about that. And I might be wrong >>> about thread safety, but using AtomicReference<State> seems to make more >>> sense. >>> >>> On 24 September 2014 11:47, Gary Gregory <garydgreg...@gmail.com> wrote: >>> >>>> On Wed, Sep 24, 2014 at 12:03 PM, Remko Popma <remko.po...@gmail.com> >>>> wrote: >>>> >>>>> >>>>> >>>>> On Wed, Sep 24, 2014 at 10:07 PM, Matt Sicker <boa...@gmail.com> >>>>> wrote: >>>>> >>>>>> Looks like I meant to add this to a different branch. This is how I >>>>>> think LifeCycle classes should work, though, so feedback would be good. >>>>>> If >>>>>> possible, I'd like to replace the current ALC with the proposed AALC >>>>>> (which >>>>>> would just be renamed to AbstractLifeCycle). >>>>>> >>>>> >>>> I have to agree here, this would be good to see in a branch for >>>> consideration in 2.2. Especially since this is unlikely to be a drop-in >>>> replacement. >>>> >>>> Gary >>>> >>>> >>>>> >>>>> Matt, if the intention was for this to go into a different branch, >>>>> then perhaps it is best to move these changes to a different branch. I >>>>> haven't had a chance to look at this in detail but it looks like quite a >>>>> big change to be making a few days before the release... For me I don't >>>>> think this week I'll be able to give it the time to review that it >>>>> deserves... >>>>> >>>>> >>>>>> >>>>>> On 24 September 2014 06:43, Gary Gregory <garydgreg...@gmail.com> >>>>>> wrote: >>>>>> >>>>>>> Hm... and why does start() behave differently in AALC from ALC? AALC >>>>>>> is not used either... so... what is it in there for? >>>>>>> >>>>>>> Gary >>>>>>> >>>>>>> On Wed, Sep 24, 2014 at 7:37 AM, Gary Gregory < >>>>>>> garydgreg...@gmail.com> wrote: >>>>>>> >>>>>>>> Do we really want two LifeCycle abstract classes? >>>>>>>> >>>>>>>> Will this not be a case -- like plug in builders vs. factory >>>>>>>> methods -- where we have two ways of doing the same thing? >>>>>>>> >>>>>>>> When do I use one vs. the other? You'd need to Javadoc that at >>>>>>>> least. >>>>>>>> >>>>>>>> Shouldn't we just have one way of doing this? >>>>>>>> >>>>>>>> Gary >>>>>>>> ---------- Forwarded message ---------- >>>>>>>> From: <mattsic...@apache.org> >>>>>>>> Date: Wed, Sep 24, 2014 at 1:39 AM >>>>>>>> Subject: [2/4] git commit: Add LifeCycle abstract class that uses >>>>>>>> AtomicReference. >>>>>>>> To: comm...@logging.apache.org >>>>>>>> >>>>>>>> >>>>>>>> Add LifeCycle abstract class that uses AtomicReference. >>>>>>>> >>>>>>>> >>>>>>>> Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo >>>>>>>> Commit: >>>>>>>> http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/1a332afa >>>>>>>> Tree: >>>>>>>> http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/1a332afa >>>>>>>> Diff: >>>>>>>> http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/1a332afa >>>>>>>> >>>>>>>> Branch: refs/heads/master >>>>>>>> Commit: 1a332afa33c55a72ae8ab5ec83cd5964de3fdc67 >>>>>>>> Parents: b701951 >>>>>>>> Author: Matt Sicker <mattsic...@apache.org> >>>>>>>> Authored: Sun Sep 21 20:30:50 2014 -0500 >>>>>>>> Committer: Matt Sicker <mattsic...@apache.org> >>>>>>>> Committed: Tue Sep 23 23:32:49 2014 -0500 >>>>>>>> >>>>>>>> >>>>>>>> ---------------------------------------------------------------------- >>>>>>>> .../log4j/core/AbstractAtomicLifeCycle.java | 102 >>>>>>>> +++++++++++++++++++ >>>>>>>> .../apache/logging/log4j/core/LifeCycle.java | 9 +- >>>>>>>> 2 files changed, 108 insertions(+), 3 deletions(-) >>>>>>>> >>>>>>>> ---------------------------------------------------------------------- >>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/1a332afa/log4j-core/src/main/java/org/apache/logging/log4j/core/AbstractAtomicLifeCycle.java >>>>>>>> >>>>>>>> ---------------------------------------------------------------------- >>>>>>>> diff --git >>>>>>>> a/log4j-core/src/main/java/org/apache/logging/log4j/core/AbstractAtomicLifeCycle.java >>>>>>>> b/log4j-core/src/main/java/org/apache/logging/log4j/core/AbstractAtomicLifeCycle.java >>>>>>>> new file mode 100644 >>>>>>>> index 0000000..05a343a >>>>>>>> --- /dev/null >>>>>>>> +++ >>>>>>>> b/log4j-core/src/main/java/org/apache/logging/log4j/core/AbstractAtomicLifeCycle.java >>>>>>>> @@ -0,0 +1,102 @@ >>>>>>>> +package org.apache.logging.log4j.core; >>>>>>>> + >>>>>>>> +import java.io.Serializable; >>>>>>>> +import java.util.concurrent.atomic.AtomicReference; >>>>>>>> + >>>>>>>> +import org.apache.logging.log4j.core.util.Throwables; >>>>>>>> +import org.apache.logging.log4j.status.StatusLogger; >>>>>>>> + >>>>>>>> +/** >>>>>>>> + * An extensible {@link LifeCycle} using an {@link >>>>>>>> AtomicReference} to wrap its {@link LifeCycle.State}. Thus, classes >>>>>>>> + * which extend this class will follow the finite state machine as >>>>>>>> follows: >>>>>>>> + * <ol> >>>>>>>> + * <li>When {@link #start()} is called, {@link #doStart()} is >>>>>>>> called if and only if this is in the INITIALIZED state or >>>>>>>> + * the STOPPED state.</li> >>>>>>>> + * <li>Before {@link #doStart()} is called, this will be in the >>>>>>>> STARTING state.</li> >>>>>>>> + * <li>After {@link #doStart()} is called, this will be in the >>>>>>>> STARTED state if no exception was thrown; otherwise, >>>>>>>> + * this will be in the INITIALIZED state again, and the exception >>>>>>>> thrown will be re-thrown (if unchecked) or wrapped >>>>>>>> + * in an {@link java.lang.reflect.UndeclaredThrowableException} >>>>>>>> and then rethrown (if checked).</li> >>>>>>>> + * <li>When {@link #stop()} is called, {@link #doStop()} is called >>>>>>>> if and only if this is in the STARTED state.</li> >>>>>>>> + * <li>Before {@link #doStop()} is called, this will be in the >>>>>>>> STOPPING state.</li> >>>>>>>> + * <li>After {@link #doStop()} is called, this will be in the >>>>>>>> STOPPED state. Any exceptions thrown will be re-thrown >>>>>>>> + * as described above.</li> >>>>>>>> + * </ol> >>>>>>>> + * >>>>>>>> + * @since 2.1 >>>>>>>> + */ >>>>>>>> +public abstract class AbstractAtomicLifeCycle implements >>>>>>>> LifeCycle, Serializable { >>>>>>>> + >>>>>>>> + private static final long serialVersionUID = 1L; >>>>>>>> + >>>>>>>> + protected static final StatusLogger LOGGER = >>>>>>>> StatusLogger.getLogger(); >>>>>>>> + >>>>>>>> + private final AtomicReference<State> state = new >>>>>>>> AtomicReference<State>(State.INITIALIZED); >>>>>>>> + >>>>>>>> + @Override >>>>>>>> + public void start() { >>>>>>>> + if (state.compareAndSet(State.INITIALIZED, State.STARTING) >>>>>>>> || >>>>>>>> + state.compareAndSet(State.STOPPED, State.STARTING)) { >>>>>>>> + try { >>>>>>>> + doStart(); >>>>>>>> + state.set(State.STARTED); >>>>>>>> + } catch (final Exception e) { >>>>>>>> + state.set(State.INITIALIZED); >>>>>>>> + Throwables.rethrow(e); >>>>>>>> + } >>>>>>>> + } >>>>>>>> + } >>>>>>>> + >>>>>>>> + /** >>>>>>>> + * Performs the start-up logic. This method is called only if >>>>>>>> this is in the INITIALIZED or STOPPED state. >>>>>>>> + * >>>>>>>> + * @throws Exception >>>>>>>> + */ >>>>>>>> + protected abstract void doStart() throws Exception; >>>>>>>> + >>>>>>>> + @Override >>>>>>>> + public void stop() { >>>>>>>> + if (state.compareAndSet(State.STARTED, State.STOPPING)) { >>>>>>>> + try { >>>>>>>> + doStop(); >>>>>>>> + } catch (Exception e) { >>>>>>>> + Throwables.rethrow(e); >>>>>>>> + } finally { >>>>>>>> + state.set(State.STOPPED); >>>>>>>> + } >>>>>>>> + } >>>>>>>> + } >>>>>>>> + >>>>>>>> + /** >>>>>>>> + * Performs the tear-down logic. This method is called only if >>>>>>>> this is in the STARTED state. >>>>>>>> + * >>>>>>>> + * @throws Exception >>>>>>>> + */ >>>>>>>> + protected abstract void doStop() throws Exception; >>>>>>>> + >>>>>>>> + @Override >>>>>>>> + public boolean isStarted() { >>>>>>>> + return state.get() == State.STARTED; >>>>>>>> + } >>>>>>>> + >>>>>>>> + @Override >>>>>>>> + public boolean isStopped() { >>>>>>>> + return state.get() == State.STOPPED; >>>>>>>> + } >>>>>>>> + >>>>>>>> + @Override >>>>>>>> + public boolean equals(final Object o) { >>>>>>>> + if (this == o) { >>>>>>>> + return true; >>>>>>>> + } >>>>>>>> + if (o == null || getClass() != o.getClass()) { >>>>>>>> + return false; >>>>>>>> + } >>>>>>>> + final AbstractAtomicLifeCycle that = >>>>>>>> (AbstractAtomicLifeCycle) o; >>>>>>>> + return state.equals(that.state); >>>>>>>> + } >>>>>>>> + >>>>>>>> + @Override >>>>>>>> + public int hashCode() { >>>>>>>> + return state.hashCode(); >>>>>>>> + } >>>>>>>> +} >>>>>>>> >>>>>>>> >>>>>>>> http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/1a332afa/log4j-core/src/main/java/org/apache/logging/log4j/core/LifeCycle.java >>>>>>>> >>>>>>>> ---------------------------------------------------------------------- >>>>>>>> diff --git >>>>>>>> a/log4j-core/src/main/java/org/apache/logging/log4j/core/LifeCycle.java >>>>>>>> b/log4j-core/src/main/java/org/apache/logging/log4j/core/LifeCycle.java >>>>>>>> index e75ebd5..191edcd 100644 >>>>>>>> --- >>>>>>>> a/log4j-core/src/main/java/org/apache/logging/log4j/core/LifeCycle.java >>>>>>>> +++ >>>>>>>> b/log4j-core/src/main/java/org/apache/logging/log4j/core/LifeCycle.java >>>>>>>> @@ -18,7 +18,7 @@ >>>>>>>> package org.apache.logging.log4j.core; >>>>>>>> >>>>>>>> /** >>>>>>>> - * All proper Java frameworks implement some sort of object life >>>>>>>> cycle. In Log4j, the main interface for handling >>>>>>>> + * Generic object life cycle support interface. In Log4j, the main >>>>>>>> interface for handling >>>>>>>> * the life cycle context of an object is this one. An object >>>>>>>> first starts in the {@link State#INITIALIZED} state >>>>>>>> * by default to indicate the class has been loaded. From here, >>>>>>>> calling the {@link #start()} method will change this >>>>>>>> * state to {@link State#STARTING}. After successfully being >>>>>>>> started, this state is changed to {@link State#STARTED}. >>>>>>>> @@ -26,9 +26,12 @@ package org.apache.logging.log4j.core; >>>>>>>> * stopped, this goes into the {@link State#STOPPED} state. In >>>>>>>> most circumstances, implementation classes should >>>>>>>> * store their {@link State} in a {@code volatile} field or inside >>>>>>>> an >>>>>>>> * {@link java.util.concurrent.atomic.AtomicReference} dependant >>>>>>>> on synchronization and concurrency requirements. >>>>>>>> + * >>>>>>>> + * @see AbstractLifeCycle >>>>>>>> + * @see AbstractAtomicLifeCycle >>>>>>>> */ >>>>>>>> public interface LifeCycle { >>>>>>>> - >>>>>>>> + >>>>>>>> /** >>>>>>>> * Status of a life cycle like a {@link LoggerContext}. >>>>>>>> */ >>>>>>>> @@ -44,7 +47,7 @@ public interface LifeCycle { >>>>>>>> /** Has stopped. */ >>>>>>>> STOPPED >>>>>>>> } >>>>>>>> - >>>>>>>> + >>>>>>>> void start(); >>>>>>>> >>>>>>>> void stop(); >>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> -- >>>>>>>> E-Mail: garydgreg...@gmail.com | ggreg...@apache.org >>>>>>>> Java Persistence with Hibernate, Second Edition >>>>>>>> <http://www.manning.com/bauer3/> >>>>>>>> JUnit in Action, Second Edition <http://www.manning.com/tahchiev/> >>>>>>>> Spring Batch in Action <http://www.manning.com/templier/> >>>>>>>> Blog: http://garygregory.wordpress.com >>>>>>>> Home: http://garygregory.com/ >>>>>>>> Tweet! http://twitter.com/GaryGregory >>>>>>>> >>>>>>> >>>>>>> >>>>>>> >>>>>>> -- >>>>>>> E-Mail: garydgreg...@gmail.com | ggreg...@apache.org >>>>>>> Java Persistence with Hibernate, Second Edition >>>>>>> <http://www.manning.com/bauer3/> >>>>>>> JUnit in Action, Second Edition <http://www.manning.com/tahchiev/> >>>>>>> Spring Batch in Action <http://www.manning.com/templier/> >>>>>>> Blog: http://garygregory.wordpress.com >>>>>>> Home: http://garygregory.com/ >>>>>>> Tweet! http://twitter.com/GaryGregory >>>>>>> >>>>>> >>>>>> >>>>>> >>>>>> -- >>>>>> Matt Sicker <boa...@gmail.com> >>>>>> >>>>> >>>>> >>>> >>>> >>>> -- >>>> E-Mail: garydgreg...@gmail.com | ggreg...@apache.org >>>> Java Persistence with Hibernate, Second Edition >>>> <http://www.manning.com/bauer3/> >>>> JUnit in Action, Second Edition <http://www.manning.com/tahchiev/> >>>> Spring Batch in Action <http://www.manning.com/templier/> >>>> Blog: http://garygregory.wordpress.com >>>> Home: http://garygregory.com/ >>>> Tweet! http://twitter.com/GaryGregory >>>> >>> >>> >>> >>> -- >>> Matt Sicker <boa...@gmail.com> >>> >> >> >> >> -- >> Matt Sicker <boa...@gmail.com> >> > > > > -- > E-Mail: garydgreg...@gmail.com | ggreg...@apache.org > Java Persistence with Hibernate, Second Edition > <http://www.manning.com/bauer3/> > JUnit in Action, Second Edition <http://www.manning.com/tahchiev/> > Spring Batch in Action <http://www.manning.com/templier/> > Blog: http://garygregory.wordpress.com > Home: http://garygregory.com/ > Tweet! http://twitter.com/GaryGregory > -- Matt Sicker <boa...@gmail.com>