How is the ACL not thread safe? I see that hashCode() could be an issue. Gary
On Wed, Sep 24, 2014 at 10:59 AM, Matt Sicker <boa...@gmail.com> wrote: > This implementation is threadsafe. > > On 24 September 2014 09:24, Gary Gregory <garydgreg...@gmail.com> wrote: > >> Hm... so how do we pick one. Are there cases w/i Log4j where we'd want >> one in one case and the other in another case? >> >> Hm... I am warming up to having the same states as OSGi... >> >> Gary >> >> On Wed, Sep 24, 2014 at 9:07 AM, 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). >>> >>> 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> > -- 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