-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Fixing Akka.Remote logging. We don't log the stack trace for known situations. (#2452) #2453
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
Fixing Akka.Remote logging. We don't log the stack trace for known situations. (#2452) #2453
Conversation
@@ -591,7 +591,7 @@ protected override SupervisorStrategy SupervisorStrategy() | |||
{ | |||
var causedBy = ia.InnerException == null | |||
? "" | |||
: string.Format("Caused by: [{0}]", ia.InnerException); | |||
: $"Caused by: [{ia.InnerException}]"; |
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 seems that the concept of the known issue was here before. If there is inner exception, we print the message and the stack trace. No changes here.
{ | ||
// Prepare a Task and pass its completion source to the manager | ||
var statusPromise = new TaskCompletionSource<AssociationHandle>(); | ||
|
||
manager.Tell(new AssociateUnderlyingRefuseUid(SchemeAugmenter.RemoveScheme(remoteAddress), statusPromise, refuseUid)); | ||
|
||
return statusPromise.Task.CastTask<AssociationHandle, AkkaProtocolHandle>(); | ||
return (AkkaProtocolHandle)await statusPromise.Task; |
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.
The code is simplified here, cause CastTask generated AggregatedException of AggregatedException of.... so on the higher level there was no way to reliably handle exceptions. I believe this should be relatively safe.
@@ -281,32 +281,36 @@ public HeliosTcpTransport(ActorSystem system, Config config) | |||
/// <param name="remoteAddress">TBD</param> | |||
/// <exception cref="HeliosConnectionException">TBD</exception> | |||
/// <returns>TBD</returns> | |||
protected override Task<AssociationHandle> AssociateInternal(Address remoteAddress) | |||
protected override async Task<AssociationHandle> AssociateInternal(Address remoteAddress) |
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 key change here. I don't think we need to throw some Helios exceptions here, cause no one is waiting them and we are not following the interface - if we know what is happening, we should throw InvalidAssociationException with Human readable message and nothing on the inner exception, if not - like usual - just don't catch it.
/// <param name="localAddress">TBD</param> | ||
/// <param name="remoteAddress">TbD</param> | ||
/// <param name="cause">TBD</param> | ||
/// <param name="disassociateInfo">TBD</param> | ||
public InvalidAssociation(Address localAddress, Address remoteAddress, Exception cause = null, DisassociateInfo? disassociateInfo = null) | ||
: base(string.Format("Invalid address: {0}", remoteAddress), cause) | ||
public InvalidAssociation(string message, Address localAddress, Address remoteAddress, Exception cause = null, DisassociateInfo? disassociateInfo = null) |
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.
Hardcoded message removed, parameter added
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.
Could you please add these as constructor overloads, rather than modifying the original constructors? I doubt that anyone is using these public APIs in their own code but for the sake of consistency, let's not modify the public API if we can avoid it.
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.
Hah! These are internal
classes. Nevermind!
} | ||
catch (Exception e) | ||
{ | ||
return new Status.Failure(e.InnerException); |
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 still get the AggregatedException here because of PipeTo - hence we take the inner exception, which is either InvalidAssociationException or some unhandled exception - in any case we propagate this further.
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 change looks good to me... I think TaskScheduler.Default
will still get used here, but even if it doesn't I don't think it will matter given how simple the continuation is (object / exception mapping.)
PublishAndThrow( | ||
new EndpointAssociationException(string.Format("Association failed with {0}", | ||
RemoteAddress)), LogLevel.DebugLevel); | ||
if (failure.Cause.InnerException == null) |
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.
In here there is a mapping from InvalidAssociationException to InvalidAssociation exception. This mapping was here before! Again - no inner exception - situation is under control - we know what is happening.
Everything else mapped and propagated with the original exception inside. Btw old implementation was hiding it.
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.
Nice catch.
{ | ||
PublishAndThrow( | ||
new EndpointAssociationException(string.Format("Association failed with {0}", | ||
RemoteAddress)), LogLevel.DebugLevel); |
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.
Here we were hiding unhandled exceptions - not cool!
return new Handle(handle.Result); | ||
}, CancellationToken.None, TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default) | ||
.PipeTo(Self); | ||
AssociateAsync().PipeTo(Self); |
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.
Same story here - simplification in order to get rid of AggregatedExceptions. I am fully following PipeTo guideline here.
case DisassociateInfo.Shutdown: | ||
throw new ShutDownAssociation(LocalAddress, RemoteAddress, new InvalidAssociationException("The remote system terminated the association because it is shutting down.")); | ||
throw new ShutDownAssociation($"The remote system terminated the association because it is shutting down. Shut down address: {RemoteAddress}", LocalAddress, RemoteAddress); |
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 unnecessary inner exceptions - no one is waiting for them on the higher level, so we were throwing them here for nothing.
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.
These changes look excellent. I'm going to review some of the MNTR logs before submitting final approval.
/// <param name="localAddress">TBD</param> | ||
/// <param name="remoteAddress">TbD</param> | ||
/// <param name="cause">TBD</param> | ||
/// <param name="disassociateInfo">TBD</param> | ||
public InvalidAssociation(Address localAddress, Address remoteAddress, Exception cause = null, DisassociateInfo? disassociateInfo = null) | ||
: base(string.Format("Invalid address: {0}", remoteAddress), cause) | ||
public InvalidAssociation(string message, Address localAddress, Address remoteAddress, Exception cause = null, DisassociateInfo? disassociateInfo = null) |
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.
Could you please add these as constructor overloads, rather than modifying the original constructors? I doubt that anyone is using these public APIs in their own code but for the sake of consistency, let's not modify the public API if we can avoid it.
/// <param name="localAddress">TBD</param> | ||
/// <param name="remoteAddress">TbD</param> | ||
/// <param name="cause">TBD</param> | ||
/// <param name="disassociateInfo">TBD</param> | ||
public InvalidAssociation(Address localAddress, Address remoteAddress, Exception cause = null, DisassociateInfo? disassociateInfo = null) | ||
: base(string.Format("Invalid address: {0}", remoteAddress), cause) | ||
public InvalidAssociation(string message, Address localAddress, Address remoteAddress, Exception cause = null, DisassociateInfo? disassociateInfo = null) |
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.
Hah! These are internal
classes. Nevermind!
} | ||
catch (Exception e) | ||
{ | ||
return new Status.Failure(e.InnerException); |
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 change looks good to me... I think TaskScheduler.Default
will still get used here, but even if it doesn't I don't think it will matter given how simple the continuation is (object / exception mapping.)
PublishAndThrow( | ||
new EndpointAssociationException(string.Format("Association failed with {0}", | ||
RemoteAddress)), LogLevel.DebugLevel); | ||
if (failure.Cause.InnerException == null) |
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.
Nice catch.
var handler = (TcpClientHandler) associate.Pipeline.Last(); | ||
return await handler.StatusFuture; | ||
} | ||
catch (AggregateException e) when (e.InnerException is ConnectException) |
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 had no idea you could even do this with when
.... that's awesome.
Just finished reviewing some of the logs from MNTR specs that kill off lots of nodes, and the logs are much much cleaner. This is excellent work. Thank you! |
The old and new logs are in the issue #2452