I didn't want to manage a pool but to do a fire and forget.

As for multiple recon figurations, I don't know of the top of my head. I don't 
want to introduce locking here but I will see if that is a problem.

Sent from my iPad

> On May 19, 2014, at 4:15 AM, Gary Gregory <[email protected]> wrote:
> 
> Does this guarantee that only one concurrent reconfiguration happens at one 
> any one time? Should it? Use a size 1 thread pool executor with a queue?
> 
> Gary
> 
> 
> -------- Original message --------
> From: [email protected]
> Date:05/19/2014 00:53 (GMT-05:00)
> To: [email protected]
> Subject: svn commit: r1595741 - in /logging/log4j/log4j2/trunk: 
> log4j-core/src/main/java/org/apache/logging/log4j/core/config/ 
> log4j-core/src/test/java/org/apache/logging/log4j/core/ 
> log4j-core/src/test/java/org/apache/logging/log4j/core/config/ 
> log4j-core/src/...
> 
> Author: rgoers
> Date: Mon May 19 04:53:11 2014
> New Revision: 1595741
> 
> URL: http://svn.apache.org/r1595741
> Log:
> LOG4J2-620 - Perform reconfiguration in a separate thread to prevent 
> deadlocks.
> 
> Added:
>     
> logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/config/ReconfigurationDeadlockTest.java
>     
> logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/test/SomethingThatUsesLogging.java
>     
> logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/test/appender/UsesLoggingAppender.java
>     
> logging/log4j/log4j2/trunk/log4j-core/src/test/resources/reconfiguration-deadlock.xml
> Modified:
>     
> logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/config/FileConfigurationMonitor.java
>     
> logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/FileConfigTest.java
>     
> logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/LoggerTest.java
>     
> logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/config/TestConfigurator.java
>     logging/log4j/log4j2/trunk/src/changes/changes.xml
> 
> Modified: 
> logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/config/FileConfigurationMonitor.java
> URL: 
> http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/config/FileConfigurationMonitor.java?rev=1595741&r1=1595740&r2=1595741&view=diff
> ==============================================================================
> --- 
> logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/config/FileConfigurationMonitor.java
>  (original)
> +++ 
> logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/config/FileConfigurationMonitor.java
>  Mon May 19 04:53:11 2014
> @@ -81,7 +81,9 @@ public class FileConfigurationMonitor im
>                  if (file.lastModified() > lastModified) {
>                      lastModified = file.lastModified();
>                      for (final ConfigurationListener listener : listeners) {
> -                        listener.onChange(reconfigurable);
> +                        Thread thread = new Thread(new 
> ReconfigurationWorker(listener, reconfigurable));
> +                        thread.setDaemon(true);
> +                        thread.start();
>                      }
>                  }
>              } finally {
> @@ -89,4 +91,20 @@ public class FileConfigurationMonitor im
>              }
>          }
>      }
> +
> +    private class ReconfigurationWorker implements Runnable {
> +
> +        private final ConfigurationListener listener;
> +        private final Reconfigurable reconfigurable;
> +
> +        public ReconfigurationWorker(ConfigurationListener listener, 
> Reconfigurable reconfigurable) {
> +            this.listener = listener;
> +            this.reconfigurable = reconfigurable;
> +        }
> +
> +        @Override
> +        public void run() {
> +            listener.onChange(reconfigurable);
> +        }
> +    }
> }
> 
> Modified: 
> logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/FileConfigTest.java
> URL: 
> http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/FileConfigTest.java?rev=1595741&r1=1595740&r2=1595741&view=diff
> ==============================================================================
> --- 
> logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/FileConfigTest.java
>  (original)
> +++ 
> logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/FileConfigTest.java
>  Mon May 19 04:53:11 2014
> @@ -81,6 +81,7 @@ public class FileConfigTest {
>          for (int i = 0; i < 17; ++i) {
>              logger.debug("Reconfigure");
>          }
> +        Thread.sleep(100);
>          final Configuration cfg = ctx.getConfiguration();
>          assertNotNull("No configuration", cfg);
>          assertTrue("Reconfiguration failed", cfg != config);
> 
> Modified: 
> logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/LoggerTest.java
> URL: 
> http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/LoggerTest.java?rev=1595741&r1=1595740&r2=1595741&view=diff
> ==============================================================================
> --- 
> logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/LoggerTest.java
>  (original)
> +++ 
> logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/LoggerTest.java
>  Mon May 19 04:53:11 2014
> @@ -238,6 +238,7 @@ public class LoggerTest {
>          for (int i = 0; i < 17; ++i) {
>              logger.debug("Reconfigure");
>          }
> +        Thread.sleep(100);
>          final Configuration cfg = ctx.getConfiguration();
>          assertNotNull("No configuration", cfg);
>          assertTrue("Reconfiguration failed", cfg != config);
> 
> Added: 
> logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/config/ReconfigurationDeadlockTest.java
> URL: 
> http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/config/ReconfigurationDeadlockTest.java?rev=1595741&view=auto
> ==============================================================================
> --- 
> logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/config/ReconfigurationDeadlockTest.java
>  (added)
> +++ 
> logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/config/ReconfigurationDeadlockTest.java
>  Mon May 19 04:53:11 2014
> @@ -0,0 +1,127 @@
> +/*
> + * Licensed to the Apache Software Foundation (ASF) under one or more
> + * contributor license agreements. See the NOTICE file distributed with
> + * this work for additional information regarding copyright ownership.
> + * The ASF licenses this file to You under the Apache license, Version 2.0
> + * (the "License"); you may not use this file except in compliance with
> + * the License. You may obtain a copy of the License at
> + *
> + *      http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to in writing, software
> + * distributed under the License is distributed on an "AS IS" BASIS,
> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
> + * See the license for the specific language governing permissions and
> + * limitations under the license.
> + */
> +package org.apache.logging.log4j.core.config;
> +
> +import org.apache.logging.log4j.LogManager;
> +import org.apache.logging.log4j.Logger;
> +import org.apache.logging.log4j.junit.InitialLoggerContext;
> +import org.apache.logging.log4j.message.ThreadDumpMessage;
> +import org.junit.Rule;
> +import org.junit.Test;
> +
> +import java.io.File;
> +
> +import static org.junit.Assert.assertTrue;
> +
> +/**
> + *
> + */
> +public class ReconfigurationDeadlockTest {
> +
> +    @Rule
> +    public InitialLoggerContext init = new 
> InitialLoggerContext("reconfiguration-deadlock.xml");
> +    private static final int THREAD_COUNT = 5;
> +    private static final boolean[] finished = new boolean[THREAD_COUNT];
> +    private static LoggerThread[] threads = new LoggerThread[THREAD_COUNT];
> +
> +    @Test
> +    public void testReconfig() throws InterruptedException {
> +
> +        Updater updater = new Updater();
> +        for (int i = 0; i < THREAD_COUNT; ++i) {
> +            threads[i] = new LoggerThread(i);
> +            threads[i].setDaemon(true);
> +        }
> +        for (int i = 0; i < THREAD_COUNT; ++i) {
> +
> +            threads[i].start();
> +        }
> +        updater.setDaemon(true);
> +        updater.start();
> +        Thread.sleep(100);
> +        boolean stillWaiting = true;
> +        for (int i = 0; i < 200; ++i) {
> +            int index = 0;
> +            for (; index < THREAD_COUNT; ++index) {
> +                if (!finished[index]) {
> +                    break;
> +                }
> +            }
> +            if (index == THREAD_COUNT) {
> +                stillWaiting = false;
> +                break;
> +            }
> +            Thread.sleep(100);
> +        }
> +        updater.shutdown = true;
> +        if (stillWaiting) {
> +            ThreadDumpMessage message = new ThreadDumpMessage("Waiting");
> +            System.err.print(message.getFormattedMessage());
> +        }
> +        for (int i = 0; i < THREAD_COUNT; ++i) {
> +            if (threads[i].isAlive()) {
> +                threads[i].interrupt();
> +            }
> +        }
> +        assertTrue("loggerThread didn't finish", stillWaiting == false);
> +
> +    }
> +
> +    private class LoggerThread extends Thread {
> +
> +        private final Logger logger = LogManager.getRootLogger();
> +        private final int index;
> +
> +        public LoggerThread(int i) {
> +            index = i;
> +        }
> +        @Override
> +        public void run() {
> +            int i = 0;
> +            try {
> +                for (i=0; i < 30; ++i) {
> +                    logger.error("Thread: " + index + ", Test: " + i++);
> +                }
> +            } catch (Exception ie) {
> +                return;
> +            }
> +            finished[index] = true;
> +        }
> +    }
> +
> +    private class Updater extends Thread {
> +
> +        public volatile boolean shutdown = false;
> +
> +        @Override
> +        public void run() {
> +            while (!shutdown) {
> +                try {
> +                    Thread.sleep(1000);
> +                } catch (InterruptedException e) {
> +                    e.printStackTrace();
> +                }
> +                // for running from IDE
> +                File file = new 
> File("target/test-classes/reconfiguration-deadlock.xml");
> +                if (file.exists()) {
> +                    file.setLastModified(System.currentTimeMillis());
> +                }
> +            }
> +        }
> +    }
> +
> +}
> 
> Modified: 
> logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/config/TestConfigurator.java
> URL: 
> http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/config/TestConfigurator.java?rev=1595741&r1=1595740&r2=1595741&view=diff
> ==============================================================================
> --- 
> logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/config/TestConfigurator.java
>  (original)
> +++ 
> logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/config/TestConfigurator.java
>  Mon May 19 04:53:11 2014
> @@ -235,6 +235,7 @@ public class TestConfigurator {
>          for (int i = 0; i < 17; ++i) {
>              logger.debug("Test message " + i);
>          }
> +        Thread.sleep(100);
>          final Configuration newConfig = ctx.getConfiguration();
>          assertTrue("Configuration not reset", newConfig != config);
>          Configurator.shutdown(ctx);
> 
> Added: 
> logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/test/SomethingThatUsesLogging.java
> URL: 
> http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/test/SomethingThatUsesLogging.java?rev=1595741&view=auto
> ==============================================================================
> --- 
> logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/test/SomethingThatUsesLogging.java
>  (added)
> +++ 
> logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/test/SomethingThatUsesLogging.java
>  Mon May 19 04:53:11 2014
> @@ -0,0 +1,36 @@
> +/*
> + * Licensed to the Apache Software Foundation (ASF) under one or more
> + * contributor license agreements. See the NOTICE file distributed with
> + * this work for additional information regarding copyright ownership.
> + * The ASF licenses this file to You under the Apache license, Version 2.0
> + * (the "License"); you may not use this file except in compliance with
> + * the License. You may obtain a copy of the License at
> + *
> + *      http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to in writing, software
> + * distributed under the License is distributed on an "AS IS" BASIS,
> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
> + * See the license for the specific language governing permissions and
> + * limitations under the license.
> + */
> +package org.apache.logging.log4j.test;
> +
> +import org.apache.logging.log4j.Level;
> +import org.apache.logging.log4j.LogManager;
> +import org.apache.logging.log4j.Logger;
> +/**
> + *
> + */
> +public class SomethingThatUsesLogging {
> +
> +    private Logger logger;
> +
> +    public SomethingThatUsesLogging() {
> +        logger = LogManager.getLogger();
> +    }
> +
> +    public void doSomething() {
> +        logger.isEnabled(Level.DEBUG);
> +    }
> +}
> 
> Added: 
> logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/test/appender/UsesLoggingAppender.java
> URL: 
> http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/test/appender/UsesLoggingAppender.java?rev=1595741&view=auto
> ==============================================================================
> --- 
> logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/test/appender/UsesLoggingAppender.java
>  (added)
> +++ 
> logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/test/appender/UsesLoggingAppender.java
>  Mon May 19 04:53:11 2014
> @@ -0,0 +1,69 @@
> +/*
> + * Licensed to the Apache Software Foundation (ASF) under one or more
> + * contributor license agreements. See the NOTICE file distributed with
> + * this work for additional information regarding copyright ownership.
> + * The ASF licenses this file to You under the Apache license, Version 2.0
> + * (the "License"); you may not use this file except in compliance with
> + * the License. You may obtain a copy of the License at
> + *
> + *      http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to in writing, software
> + * distributed under the License is distributed on an "AS IS" BASIS,
> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
> + * See the license for the specific language governing permissions and
> + * limitations under the license.
> + */
> +package org.apache.logging.log4j.test.appender;
> +
> +import org.apache.logging.log4j.core.Filter;
> +import org.apache.logging.log4j.core.Layout;
> +import org.apache.logging.log4j.core.LogEvent;
> +import org.apache.logging.log4j.core.appender.AbstractAppender;
> +import org.apache.logging.log4j.core.config.plugins.Plugin;
> +import org.apache.logging.log4j.core.config.plugins.PluginAttribute;
> +import org.apache.logging.log4j.core.config.plugins.PluginElement;
> +import org.apache.logging.log4j.core.config.plugins.PluginFactory;
> +import org.apache.logging.log4j.test.SomethingThatUsesLogging;
> +
> +/**
> + *
> + */
> +@Plugin(name = "UsesLoggingAppender", category = "Core", elementType = 
> "appender", printObject = true)
> +public final class UsesLoggingAppender extends AbstractAppender {
> +
> +    private SomethingThatUsesLogging thing;
> +
> +    private UsesLoggingAppender(String name, Filter filter, Layout<?> 
> layout, boolean ignoreExceptions) {
> +        super(name, filter, layout, ignoreExceptions);
> +        thing = new SomethingThatUsesLogging();
> +    }
> +
> +    @PluginFactory
> +    public static UsesLoggingAppender 
> createAppender(@PluginAttribute("name") String name,
> +                                            
> @PluginAttribute("ignoreExceptions") String ignore,
> +                                            @PluginElement("Layout") 
> Layout<?> layout,
> +                                            @PluginElement("Filters") Filter 
> filter) {
> +
> +        boolean ignoreExceptions = Boolean.parseBoolean(ignore);
> +
> +        if (name == null) {
> +            LOGGER.error("No name provided for MyAppender");
> +            return null;
> +        }
> +
> +        return new UsesLoggingAppender(name, filter, layout, 
> ignoreExceptions);
> +    }
> +
> +    public void append(LogEvent event) {
> +        try {
> +            for (int i = 0; i < 50; i++) {
> +                Thread.sleep(10);
> +                thing.doSomething();
> +            }
> +        } catch (InterruptedException e) {
> +            e.printStackTrace();
> +        }
> +        // System.out.print("Log: " + getLayout().toSerializable(event));
> +    }
> +}
> 
> Added: 
> logging/log4j/log4j2/trunk/log4j-core/src/test/resources/reconfiguration-deadlock.xml
> URL: 
> http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/log4j-core/src/test/resources/reconfiguration-deadlock.xml?rev=1595741&view=auto
> ==============================================================================
> --- 
> logging/log4j/log4j2/trunk/log4j-core/src/test/resources/reconfiguration-deadlock.xml
>  (added)
> +++ 
> logging/log4j/log4j2/trunk/log4j-core/src/test/resources/reconfiguration-deadlock.xml
>  Mon May 19 04:53:11 2014
> @@ -0,0 +1,19 @@
> +<?xml version="1.0" encoding="UTF-8"?>
> +<Configuration status="error" monitorInterval="5">
> +  <Appenders>
> +    <UsesLoggingAppender name="myAppender">
> +      <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - 
> %msg%n" />
> +    </UsesLoggingAppender>
> +    <Console name="STDOUT">
> +      <PatternLayout pattern="%m%n"/>
> +    </Console>
> +  </Appenders>
> +  <Loggers>
> +    <Logger name="Dump" level="trace" additivity="false">
> +      <AppenderRef ref="STDOUT" />
> +    </Logger>
> +    <Root level="ERROR">
> +      <AppenderRef ref="myAppender" />
> +    </Root>
> +  </Loggers>
> +</Configuration>
> \ No newline at end of file
> 
> Modified: logging/log4j/log4j2/trunk/src/changes/changes.xml
> URL: 
> http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/src/changes/changes.xml?rev=1595741&r1=1595740&r2=1595741&view=diff
> ==============================================================================
> --- logging/log4j/log4j2/trunk/src/changes/changes.xml (original)
> +++ logging/log4j/log4j2/trunk/src/changes/changes.xml Mon May 19 04:53:11 
> 2014
> @@ -22,6 +22,9 @@
>    </properties>
>    <body>
>      <release version="2.0-rc2" date="2014-MM-DD" description="Bug fixes and 
> enhancements">
> +      <action issue="LOG4J2-620" dev="rgoers" type="fix">
> +        Perform reconfiguration in a separate thread to prevent deadlocks.
> +      </action>
>        <action issue="LOG4J2-641" dev="mattsicker" type="update">
>          Override commons-logging dependency version in tests.
>        </action>
> 
> 

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to