Activity

On reconfiguration, a new Disruptor instance is created, but no new thread pool is created. The new Disruptor instances references the old thread pool, which has been shut down (or is in the middle of shutting down), resulting in various errors. The solution is to create a new thread pool object every time a new Disruptor instance is created.

Remko Popma
added a comment - 08/Aug/13 02:22 Thanks for finding this.
On reconfiguration, a new Disruptor instance is created, but no new thread pool is created. The new Disruptor instances references the old thread pool, which has been shut down (or is in the middle of shutting down), resulting in various errors. The solution is to create a new thread pool object every time a new Disruptor instance is created.

Yes, this will be fixed with beta9. Not sure when that will be, community decision. Perhaps a few weeks from now?

BTW, sorry I haven't had time to run your test case, but I assume you see the same issue (or worse) when making all loggers Async Loggers? (by setting -DLog4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector)?

Remko Popma
added a comment - 08/Aug/13 10:09 Yes, this will be fixed with beta9. Not sure when that will be, community decision. Perhaps a few weeks from now?
BTW, sorry I haven't had time to run your test case, but I assume you see the same issue (or worse) when making all loggers Async Loggers? (by setting -DLog4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector)?

I was finally able to track this down to an unbalanced number of calls to LoggerConfig#startFilter and #stopFilter. In o.a.l.l.c.c.BaseConfiguration, the #stop() method explicitly calls the #stopFilter() method on the root logger, but there is no equivalent call to root#startFilter in the BaseConfiguration#start() method.

This means that the reference count (used to determine when to shut down or create new Disruptor instances) is incorrect when the configuration contains a <asyncRoot> element.

Note that the #startFilter and #stopFilter methods may be called twice for the root logger. Not ideal, but better than stopping twice for every start. Based on current usage I don't see any problems. FYI, currently AsyncLoggerConfig is the only LoggerConfig that overrides the default #startFilter and #stopFilter implementation.

Remko Popma
added a comment - 14/Aug/13 01:36 I was finally able to track this down to an unbalanced number of calls to LoggerConfig#startFilter and #stopFilter. In o.a.l.l.c.c.BaseConfiguration, the #stop() method explicitly calls the #stopFilter() method on the root logger, but there is no equivalent call to root#startFilter in the BaseConfiguration#start() method.
This means that the reference count (used to determine when to shut down or create new Disruptor instances) is incorrect when the configuration contains a <asyncRoot> element.
Proposed solution:
// o.a.l.l.c.c.BaseConfiguration
public void start() {
setup();
doConfigure();
for ( final LoggerConfig logger : loggers.values()) {
logger.startFilter();
}
for ( final Appender appender : appenders.values()) {
appender.start();
}
root.startFilter(); // add this line
startFilter();
}
Note that the #startFilter and #stopFilter methods may be called twice for the root logger. Not ideal, but better than stopping twice for every start. Based on current usage I don't see any problems. FYI, currently AsyncLoggerConfig is the only LoggerConfig that overrides the default #startFilter and #stopFilter implementation.

Remko Popma
added a comment - 14/Aug/13 13:03 Andre, during a reconfigure, new Appenders and LoggerConfig objects are created and started, and the old ones are all stopped, including the old root LoggerConfig.

Andre, one reason I can see is that it is possible to create a configuration without a root element. In that case a default root element is created automatically (with a console Appender, ERROR level and a default layout). In this scenario the root logger is not part of the loggers Map.

As far as I can tell, the root logger would be part of the loggers Map if a <root> (or <asyncRoot>) logger is configured in the configuration file.

Remko Popma
added a comment - 14/Aug/13 13:35 Andre, one reason I can see is that it is possible to create a configuration without a root element. In that case a default root element is created automatically (with a console Appender, ERROR level and a default layout). In this scenario the root logger is not part of the loggers Map.
As far as I can tell, the root logger would be part of the loggers Map if a <root> (or <asyncRoot> ) logger is configured in the configuration file.

Wouldn't adding a default root logger into the loggers Map even if one isn't configured be a more general solution? Edit: I've just checked out the trunk, will compile, verify and hopefully close this issue shortly.

Andre Bogus
added a comment - 14/Aug/13 14:59 - edited Wouldn't adding a default root logger into the loggers Map even if one isn't configured be a more general solution? Edit: I've just checked out the trunk, will compile, verify and hopefully close this issue shortly.