You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by ma...@apache.org on 2014/09/24 07:39:12 UTC

[2/4] git commit: Add LifeCycle abstract class that uses AtomicReference.

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 <ma...@apache.org>
Authored: Sun Sep 21 20:30:50 2014 -0500
Committer: Matt Sicker <ma...@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();


Re: [2/4] git commit: Add LifeCycle abstract class that uses AtomicReference.

Posted by Matt Sicker <bo...@gmail.com>.
https://issues.apache.org/jira/browse/LOG4J2-859

On 24 September 2014 21:07, Gary Gregory <ga...@gmail.com> wrote:

> Revisit for 2.2...
>
> Gary
>
> On Wed, Sep 24, 2014 at 9:59 PM, Matt Sicker <bo...@gmail.com> wrote:
>
>> Reverted the commit.
>>
>> On 24 September 2014 14:30, Matt Sicker <bo...@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 <ga...@gmail.com> wrote:
>>>
>>>> On Wed, Sep 24, 2014 at 12:03 PM, Remko Popma <re...@gmail.com>
>>>> wrote:
>>>>
>>>>>
>>>>>
>>>>> On Wed, Sep 24, 2014 at 10:07 PM, Matt Sicker <bo...@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 <ga...@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 <
>>>>>>> garydgregory@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: <ma...@apache.org>
>>>>>>>> Date: Wed, Sep 24, 2014 at 1:39 AM
>>>>>>>> Subject: [2/4] git commit: Add LifeCycle abstract class that uses
>>>>>>>> AtomicReference.
>>>>>>>> To: commits@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 <ma...@apache.org>
>>>>>>>> Authored: Sun Sep 21 20:30:50 2014 -0500
>>>>>>>> Committer: Matt Sicker <ma...@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: garydgregory@gmail.com | ggregory@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: garydgregory@gmail.com | ggregory@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 <bo...@gmail.com>
>>>>>>
>>>>>
>>>>>
>>>>
>>>>
>>>> --
>>>> E-Mail: garydgregory@gmail.com | ggregory@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 <bo...@gmail.com>
>>>
>>
>>
>>
>> --
>> Matt Sicker <bo...@gmail.com>
>>
>
>
>
> --
> E-Mail: garydgregory@gmail.com | ggregory@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 <bo...@gmail.com>

Re: [2/4] git commit: Add LifeCycle abstract class that uses AtomicReference.

Posted by Gary Gregory <ga...@gmail.com>.
Revisit for 2.2...

Gary

On Wed, Sep 24, 2014 at 9:59 PM, Matt Sicker <bo...@gmail.com> wrote:

> Reverted the commit.
>
> On 24 September 2014 14:30, Matt Sicker <bo...@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 <ga...@gmail.com> wrote:
>>
>>> On Wed, Sep 24, 2014 at 12:03 PM, Remko Popma <re...@gmail.com>
>>> wrote:
>>>
>>>>
>>>>
>>>> On Wed, Sep 24, 2014 at 10:07 PM, Matt Sicker <bo...@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 <ga...@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 <garydgregory@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: <ma...@apache.org>
>>>>>>> Date: Wed, Sep 24, 2014 at 1:39 AM
>>>>>>> Subject: [2/4] git commit: Add LifeCycle abstract class that uses
>>>>>>> AtomicReference.
>>>>>>> To: commits@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 <ma...@apache.org>
>>>>>>> Authored: Sun Sep 21 20:30:50 2014 -0500
>>>>>>> Committer: Matt Sicker <ma...@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: garydgregory@gmail.com | ggregory@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: garydgregory@gmail.com | ggregory@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 <bo...@gmail.com>
>>>>>
>>>>
>>>>
>>>
>>>
>>> --
>>> E-Mail: garydgregory@gmail.com | ggregory@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 <bo...@gmail.com>
>>
>
>
>
> --
> Matt Sicker <bo...@gmail.com>
>



-- 
E-Mail: garydgregory@gmail.com | ggregory@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

Re: [2/4] git commit: Add LifeCycle abstract class that uses AtomicReference.

Posted by Matt Sicker <bo...@gmail.com>.
Reverted the commit.

On 24 September 2014 14:30, Matt Sicker <bo...@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 <ga...@gmail.com> wrote:
>
>> On Wed, Sep 24, 2014 at 12:03 PM, Remko Popma <re...@gmail.com>
>> wrote:
>>
>>>
>>>
>>> On Wed, Sep 24, 2014 at 10:07 PM, Matt Sicker <bo...@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 <ga...@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 <ga...@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: <ma...@apache.org>
>>>>>> Date: Wed, Sep 24, 2014 at 1:39 AM
>>>>>> Subject: [2/4] git commit: Add LifeCycle abstract class that uses
>>>>>> AtomicReference.
>>>>>> To: commits@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 <ma...@apache.org>
>>>>>> Authored: Sun Sep 21 20:30:50 2014 -0500
>>>>>> Committer: Matt Sicker <ma...@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: garydgregory@gmail.com | ggregory@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: garydgregory@gmail.com | ggregory@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 <bo...@gmail.com>
>>>>
>>>
>>>
>>
>>
>> --
>> E-Mail: garydgregory@gmail.com | ggregory@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 <bo...@gmail.com>
>



-- 
Matt Sicker <bo...@gmail.com>

Re: [2/4] git commit: Add LifeCycle abstract class that uses AtomicReference.

Posted by Matt Sicker <bo...@gmail.com>.
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 <ga...@gmail.com> wrote:

> On Wed, Sep 24, 2014 at 12:03 PM, Remko Popma <re...@gmail.com>
> wrote:
>
>>
>>
>> On Wed, Sep 24, 2014 at 10:07 PM, Matt Sicker <bo...@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 <ga...@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 <ga...@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: <ma...@apache.org>
>>>>> Date: Wed, Sep 24, 2014 at 1:39 AM
>>>>> Subject: [2/4] git commit: Add LifeCycle abstract class that uses
>>>>> AtomicReference.
>>>>> To: commits@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 <ma...@apache.org>
>>>>> Authored: Sun Sep 21 20:30:50 2014 -0500
>>>>> Committer: Matt Sicker <ma...@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: garydgregory@gmail.com | ggregory@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: garydgregory@gmail.com | ggregory@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 <bo...@gmail.com>
>>>
>>
>>
>
>
> --
> E-Mail: garydgregory@gmail.com | ggregory@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 <bo...@gmail.com>

Re: [2/4] git commit: Add LifeCycle abstract class that uses AtomicReference.

Posted by Gary Gregory <ga...@gmail.com>.
On Wed, Sep 24, 2014 at 12:03 PM, Remko Popma <re...@gmail.com> wrote:

>
>
> On Wed, Sep 24, 2014 at 10:07 PM, Matt Sicker <bo...@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 <ga...@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 <ga...@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: <ma...@apache.org>
>>>> Date: Wed, Sep 24, 2014 at 1:39 AM
>>>> Subject: [2/4] git commit: Add LifeCycle abstract class that uses
>>>> AtomicReference.
>>>> To: commits@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 <ma...@apache.org>
>>>> Authored: Sun Sep 21 20:30:50 2014 -0500
>>>> Committer: Matt Sicker <ma...@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: garydgregory@gmail.com | ggregory@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: garydgregory@gmail.com | ggregory@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 <bo...@gmail.com>
>>
>
>


-- 
E-Mail: garydgregory@gmail.com | ggregory@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

Re: [2/4] git commit: Add LifeCycle abstract class that uses AtomicReference.

Posted by Remko Popma <re...@gmail.com>.
On Wed, Sep 24, 2014 at 10:07 PM, Matt Sicker <bo...@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).
>

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 <ga...@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 <ga...@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: <ma...@apache.org>
>>> Date: Wed, Sep 24, 2014 at 1:39 AM
>>> Subject: [2/4] git commit: Add LifeCycle abstract class that uses
>>> AtomicReference.
>>> To: commits@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 <ma...@apache.org>
>>> Authored: Sun Sep 21 20:30:50 2014 -0500
>>> Committer: Matt Sicker <ma...@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: garydgregory@gmail.com | ggregory@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: garydgregory@gmail.com | ggregory@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 <bo...@gmail.com>
>

Re: [2/4] git commit: Add LifeCycle abstract class that uses AtomicReference.

Posted by Gary Gregory <ga...@gmail.com>.
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 <bo...@gmail.com> wrote:

> This implementation is threadsafe.
>
> On 24 September 2014 09:24, Gary Gregory <ga...@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 <bo...@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 <ga...@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 <ga...@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: <ma...@apache.org>
>>>>> Date: Wed, Sep 24, 2014 at 1:39 AM
>>>>> Subject: [2/4] git commit: Add LifeCycle abstract class that uses
>>>>> AtomicReference.
>>>>> To: commits@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 <ma...@apache.org>
>>>>> Authored: Sun Sep 21 20:30:50 2014 -0500
>>>>> Committer: Matt Sicker <ma...@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: garydgregory@gmail.com | ggregory@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: garydgregory@gmail.com | ggregory@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 <bo...@gmail.com>
>>>
>>
>>
>>
>> --
>> E-Mail: garydgregory@gmail.com | ggregory@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 <bo...@gmail.com>
>



-- 
E-Mail: garydgregory@gmail.com | ggregory@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

Re: [2/4] git commit: Add LifeCycle abstract class that uses AtomicReference.

Posted by Matt Sicker <bo...@gmail.com>.
This implementation is threadsafe.

On 24 September 2014 09:24, Gary Gregory <ga...@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 <bo...@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 <ga...@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 <ga...@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: <ma...@apache.org>
>>>> Date: Wed, Sep 24, 2014 at 1:39 AM
>>>> Subject: [2/4] git commit: Add LifeCycle abstract class that uses
>>>> AtomicReference.
>>>> To: commits@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 <ma...@apache.org>
>>>> Authored: Sun Sep 21 20:30:50 2014 -0500
>>>> Committer: Matt Sicker <ma...@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: garydgregory@gmail.com | ggregory@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: garydgregory@gmail.com | ggregory@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 <bo...@gmail.com>
>>
>
>
>
> --
> E-Mail: garydgregory@gmail.com | ggregory@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 <bo...@gmail.com>

Re: [2/4] git commit: Add LifeCycle abstract class that uses AtomicReference.

Posted by Gary Gregory <ga...@gmail.com>.
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 <bo...@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 <ga...@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 <ga...@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: <ma...@apache.org>
>>> Date: Wed, Sep 24, 2014 at 1:39 AM
>>> Subject: [2/4] git commit: Add LifeCycle abstract class that uses
>>> AtomicReference.
>>> To: commits@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 <ma...@apache.org>
>>> Authored: Sun Sep 21 20:30:50 2014 -0500
>>> Committer: Matt Sicker <ma...@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: garydgregory@gmail.com | ggregory@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: garydgregory@gmail.com | ggregory@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 <bo...@gmail.com>
>



-- 
E-Mail: garydgregory@gmail.com | ggregory@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

Re: [2/4] git commit: Add LifeCycle abstract class that uses AtomicReference.

Posted by Matt Sicker <bo...@gmail.com>.
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 <ga...@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 <ga...@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: <ma...@apache.org>
>> Date: Wed, Sep 24, 2014 at 1:39 AM
>> Subject: [2/4] git commit: Add LifeCycle abstract class that uses
>> AtomicReference.
>> To: commits@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 <ma...@apache.org>
>> Authored: Sun Sep 21 20:30:50 2014 -0500
>> Committer: Matt Sicker <ma...@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: garydgregory@gmail.com | ggregory@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: garydgregory@gmail.com | ggregory@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 <bo...@gmail.com>

Re: [2/4] git commit: Add LifeCycle abstract class that uses AtomicReference.

Posted by Gary Gregory <ga...@gmail.com>.
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 <ga...@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: <ma...@apache.org>
> Date: Wed, Sep 24, 2014 at 1:39 AM
> Subject: [2/4] git commit: Add LifeCycle abstract class that uses
> AtomicReference.
> To: commits@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 <ma...@apache.org>
> Authored: Sun Sep 21 20:30:50 2014 -0500
> Committer: Matt Sicker <ma...@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: garydgregory@gmail.com | ggregory@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: garydgregory@gmail.com | ggregory@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

Fwd: [2/4] git commit: Add LifeCycle abstract class that uses AtomicReference.

Posted by Gary Gregory <ga...@gmail.com>.
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: <ma...@apache.org>
Date: Wed, Sep 24, 2014 at 1:39 AM
Subject: [2/4] git commit: Add LifeCycle abstract class that uses
AtomicReference.
To: commits@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 <ma...@apache.org>
Authored: Sun Sep 21 20:30:50 2014 -0500
Committer: Matt Sicker <ma...@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: garydgregory@gmail.com | ggregory@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