Skip to content

Commit

Permalink
Trimming and AOT compatibility
Browse files Browse the repository at this point in the history
Resolve the trim warning coming from RabbitMqClientEventSource.Error. Preserve the properties of RabbitMqExceptionDetail and suppress the warning.

The TimerBasedCredentialRefresherEventSource has warnings as well, but these can be suppressed because the parameters are primitive. In .NET 8 these warnings no longer need to be suppressed because of dotnet/runtime#83751.

Fix #1410
  • Loading branch information
eerhardt committed Oct 31, 2023
1 parent a0321c6 commit 4c47085
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 16 deletions.
1 change: 1 addition & 0 deletions projects/RabbitMQ.Client/RabbitMQ.Client.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
<TargetFrameworks>net6.0;netstandard2.0</TargetFrameworks>
<NoWarn>$(NoWarn);CS1591</NoWarn>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<EnableTrimAnalyzer>true</EnableTrimAnalyzer>
<AssemblyTitle>RabbitMQ Client Library for .NET</AssemblyTitle>
<Authors>VMware</Authors>
<Company>VMware, Inc. or its affiliates.</Company>
Expand Down
11 changes: 9 additions & 2 deletions projects/RabbitMQ.Client/client/api/ICredentialsRefresher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@

using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Diagnostics.Tracing;
namespace RabbitMQ.Client
{
Expand All @@ -39,7 +40,7 @@ public interface ICredentialsRefresher
ICredentialsProvider Register(ICredentialsProvider provider, NotifyCredentialRefreshed callback);
bool Unregister(ICredentialsProvider provider);

delegate void NotifyCredentialRefreshed(bool succesfully);
delegate void NotifyCredentialRefreshed(bool successfully);
}

[EventSource(Name = "TimerBasedCredentialRefresher")]
Expand All @@ -52,11 +53,17 @@ public class TimerBasedCredentialRefresherEventSource : EventSource
[Event(2)]
public void Unregistered(string name) => WriteEvent(2, "UnRegistered", name);
[Event(3)]
#if NET6_0_OR_GREATER
[UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", Justification = "Parameters to this method are primitive and are trimmer safe")]
#endif
public void ScheduledTimer(string name, double interval) => WriteEvent(3, "ScheduledTimer", name, interval);
[Event(4)]
public void TriggeredTimer(string name) => WriteEvent(4, "TriggeredTimer", name);
[Event(5)]
public void RefreshedCredentials(string name, bool succesfully) => WriteEvent(5, "RefreshedCredentials", name, succesfully);
#if NET6_0_OR_GREATER
[UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", Justification = "Parameters to this method are primitive and are trimmer safe")]
#endif
public void RefreshedCredentials(string name, bool successfully) => WriteEvent(5, "RefreshedCredentials", name, successfully);
}

public class TimerBasedCredentialRefresher : ICredentialsRefresher
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
//---------------------------------------------------------------------------

using System;
using System.Diagnostics.CodeAnalysis;
using System.Diagnostics.Tracing;

namespace RabbitMQ.Client.Logging
Expand Down Expand Up @@ -62,31 +63,30 @@ public void Warn(string message)
if (IsEnabled())
WriteEvent(2, message);
}
#if NET452
[Event(3, Message = "ERROR", Keywords = Keywords.Log, Level = EventLevel.Error)]
public void Error(string message, string detail)
{
if(IsEnabled())
this.WriteEvent(3, message, detail);
}
#else

[Event(3, Message = "ERROR", Keywords = Keywords.Log, Level = EventLevel.Error)]
public void Error(string message, RabbitMqExceptionDetail ex)
{
if (IsEnabled())
{
#if NET6_0_OR_GREATER
WriteExceptionEvent(message, ex);

[UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "The properties are preserved with the DynamicallyAccessedMembers attribute.")]
void WriteExceptionEvent<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)] T>(string message, T ex)
{
WriteEvent(3, message, ex);
}
#else
WriteEvent(3, message, ex);
}
#endif
}
}

[NonEvent]
public void Error(string message, Exception ex)
{

#if NET452
Error(message, ex.ToString());
#else
Error(message, new RabbitMqExceptionDetail(ex));
#endif
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ public RabbitMqExceptionDetail(IDictionary<string, object> ex)
}
}

// NOTE: This type is used to write EventData in RabbitMqClientEventSource.Error. To make it trim-compatible, these properties are preserved
// in RabbitMqClientEventSource. If RabbitMqExceptionDetail gets a property that is a complex type, we need to ensure the nested properties are
// preserved as well.

public string Type { get; }
public string Message { get; }
public string StackTrace { get; }
Expand Down

0 comments on commit 4c47085

Please sign in to comment.