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>