New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix faulty AddLogger in LoggingBus #6028
Fix faulty AddLogger in LoggingBus #6028
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Have some questions and one minor requested change
@Arkatufus this will need to be sent to v1.5 as well? |
@Aaronontheweb yeah, I'll make a port when this is done |
This is the original fix: It was made because |
@Aaronontheweb |
src/core/Akka/Event/LoggingBus.cs
Outdated
foreach (var strLoggerType in loggerTypes) | ||
{ | ||
var loggerType = Type.GetType(strLoggerType); | ||
if (loggerType == null) | ||
{ | ||
throw new ConfigurationException($@"Logger specified in config cannot be found: ""{strLoggerType}"""); | ||
Publish(new Error(null, logName, GetType(), $@"Logger specified in config cannot be found: ""{strLoggerType}""")); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We log an error instead of stopping the ActorSystem when a logger type can not be found
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you consider a logger to be critical infrastructure, isn't this a bad idea? i.e. if I don't have visibility into how my service runs at a basic level, how can I be sure it's working correctly?
I'd probably leave the old fail-fast mechanic in-place, which should be even rarer now with the changes in Akka.Hosting.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is different than the logger taking too long to startup - nothing is necessarily wrong with the users' configuration in that case. But in this case, the user's config is 100% wrong and they must fix it. That's why throwing an error here is a good idea.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Alright, I'll bring the exception code back
src/core/Akka/Event/LoggingBus.cs
Outdated
AddLogger(system, loggerType, logName); | ||
} | ||
|
||
if (!Task.WaitAll(_startupState.Keys.ToArray(), timeout)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We will wait for all loggers to be ready here, limiting the time to the timeout period.
The pro of this is that, instead of waiting for a timeout period for each loggers, we only wait once for everything, all logger Ask
operation are performed concurrently.
{ | ||
throw new ConfigurationException($"Logger [{strLoggerType}] specified in config cannot be loaded: {ex}", ex); | ||
Publish(new Warning(logName, GetType(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We log a warning if any of the Ask
-ed loggers hasn't replied after the Wait
@@ -164,46 +173,68 @@ internal void StopDefaultLoggers(ActorSystem system) | |||
Publish(new Debug(SimpleName(this), GetType(), $"Shutting down: {Logging.SimpleName(system.Settings.StdoutLogger)} started")); | |||
} | |||
|
|||
// Cancel all pending logger initialization tasks | |||
_shutdownCts.Cancel(false); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the mechanism to shutdown all pending Ask
if they're still in progress even when the ActorSystem is shutting down.
|
||
_startupState[askTask] = new LoggerStartInfo(loggerName, loggerType, logger); | ||
askTask.ContinueWith(t => |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We process all Ask
result with a continuation here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Has some issues
src/core/Akka/Event/LoggingBus.cs
Outdated
foreach (var strLoggerType in loggerTypes) | ||
{ | ||
var loggerType = Type.GetType(strLoggerType); | ||
if (loggerType == null) | ||
{ | ||
throw new ConfigurationException($@"Logger specified in config cannot be found: ""{strLoggerType}"""); | ||
Publish(new Error(null, logName, GetType(), $@"Logger specified in config cannot be found: ""{strLoggerType}""")); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you consider a logger to be critical infrastructure, isn't this a bad idea? i.e. if I don't have visibility into how my service runs at a basic level, how can I be sure it's working correctly?
I'd probably leave the old fail-fast mechanic in-place, which should be even rarer now with the changes in Akka.Hosting.
src/core/Akka/Event/LoggingBus.cs
Outdated
_startupState[askTask] = new LoggerStartInfo(loggerName, loggerType, logger); | ||
askTask.ContinueWith(t => | ||
{ | ||
var info = _startupState[t]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not safe to do this in a continuation, since this is now shared mutable state.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd keep the rest of the continuation but basically just purge the _startupState
after the Task.WaitAll
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It should be safe since this is the only class where it is modified and there is no cross-pollination, each task handles its own continuation and have their own Task as their key.
We had to held on to _startupState
because of the possibility that some loggers are not ready after the Task.WaitAll
and they needed to retrieve their info. Would it be safe to use closure instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed the dictionary, changed it to closure. Just needed the logger name for logging purposes outside of the Task continuation
src/core/Akka/Event/LoggingBus.cs
Outdated
foreach (var strLoggerType in loggerTypes) | ||
{ | ||
var loggerType = Type.GetType(strLoggerType); | ||
if (loggerType == null) | ||
{ | ||
throw new ConfigurationException($@"Logger specified in config cannot be found: ""{strLoggerType}"""); | ||
Publish(new Error(null, logName, GetType(), $@"Logger specified in config cannot be found: ""{strLoggerType}""")); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is different than the logger taking too long to startup - nothing is necessarily wrong with the users' configuration in that case. But in this case, the user's config is 100% wrong and they must fix it. That's why throwing an error here is a good idea.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
@Arkatufus needs a backport to v1.5 |
* Fix faulty AddLogger in LoggingBus * Ignore logger async start setting, not relevant anymore * Simplify unit test * Send Stop instead of PoisonPill * Make loggers load asynchronously by default * Change logging back to exceptions * Remove _startupState, use closure instead Co-authored-by: Aaron Stannard <aaron@petabridge.com> (cherry picked from commit c8b46b4)
* Fix faulty AddLogger in LoggingBus * Ignore logger async start setting, not relevant anymore * Simplify unit test * Send Stop instead of PoisonPill * Make loggers load asynchronously by default * Change logging back to exceptions * Remove _startupState, use closure instead Co-authored-by: Aaron Stannard <aaron@petabridge.com> (cherry picked from commit c8b46b4)
Exception handling inside AddLogger is wrong