Skip to content
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

Create one session/telemetry configuration per run #515

Merged
merged 7 commits into from
Nov 10, 2021

Conversation

eddynaka
Copy link
Contributor

@eddynaka eddynaka commented Nov 6, 2021

Description:

When we changed from single thread to multi-thread application, the reporting rule started to behave differently:

  • many configurations were being created
  • many sessions were being created
  • hash wasn't showing correctly since the hash isn't calculated previously

Fixes:

This PR will fix the following issues:

  • session/telemetry objects should not be overridden if already exists
  • session/telemetry objects should be created only once (even in a multithread environment)
  • hash should have a reference to the context since it will be only created once we start loading a specific file

@@ -20,15 +20,19 @@
private const string CommandLineEventName = "CommandLineInformation";
private const string AssemblyReferencesEventName = "AssemblyReferencesInformation";

private readonly int ChunkSize;
private readonly string sha256;
private string Sha256 => context?.Hashes?.Sha256;
Copy link
Contributor Author

@eddynaka eddynaka Nov 6, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

context?.Hashes?.Sha256

since we changed how hashes are generated, we should make a reference to the context so we will have the correct value of the hash when needed. #ByDesign

s_telemetryClient = telemetryClient;
s_sessionId = TelemetryEnabled ? Guid.NewGuid().ToString() : null;
ChunkSize = chunkSize;
s_telemetryConfiguration ??= telemetryConfiguration;
Copy link
Contributor Author

@eddynaka eddynaka Nov 6, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

telemetryConfiguration

we should only use telemetryConfiguration/telemetryClient if the respective static value is null. This should only be used during tests. #ByDesign

@eddynaka eddynaka changed the title Create one session per run Create one session/telemetry configuration per run Nov 6, 2021
@eddynaka eddynaka marked this pull request as ready for review November 6, 2021 19:17
@@ -20,15 +20,19 @@ public class CompilerDataLogger
private const string CommandLineEventName = "CommandLineInformation";
private const string AssemblyReferencesEventName = "AssemblyReferencesInformation";

private readonly int ChunkSize;
private readonly string sha256;
private string Sha256 => context?.Hashes?.Sha256;
Copy link
Member

@michaelcfanning michaelcfanning Nov 9, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

context

the code previously seemed to return string.empty in the null case, is that still required or is it ok to drop it? #Closed

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

when we send a null to AppInsights, it won't render the key value pair. If we try to print it in console, a null is showed as an empty string.

so, in this case, we don't need to create a default to empty


private static string s_sessionId;
internal static string s_sessionId;
Copy link
Member

@michaelcfanning michaelcfanning Nov 9, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

internal

please pull aside all the internal static properties (that are overridden by tests) and group them together.

we do this to improve the readability of code, i.e., that accessibility is a clue to the maintainer there is a special external caller (our tests) that update these values.

make sense? you are future-proofing this code to help whoever comes along when those tests fail. #Closed

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it!
thanks for the feedback!

s_telemetryClient = new TelemetryClient(s_telemetryConfiguration);
lock (s_syncRoot)
{
if (s_telemetryConfiguration == null && s_telemetryClient == null)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s_telemetryClient

I don't understand the visibility of things in your class, why is s_sessionId internal but s_telemetry not?

Why is it ok to allow s_sessionId to be overridden by tests but then overwritten again if these two values are null?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

session/configuration/client can be injected using the constructor but the session is always defined when we have the telemetry enabled.

It's why we don't need to make the configuration/client internal.

}
}

internal static void Reset()
{
s_sessionId = null;
Copy link
Member

@michaelcfanning michaelcfanning Nov 9, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s_sessionId

why don't you lock here? #Resolved

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added some docs in this method. We don't need a lock because it will only be called during tests.
All the tests that requires this aren't running in parallel.


[assembly: AssemblyTitle("BinSkim SDK")]
[assembly: AssemblyDescription("BinSkim SDK and utilities for authoring analysis checks")]

[assembly: InternalsVisibleTo("Test.UnitTests.BinSkim.Driver")]
Copy link
Member

@michaelcfanning michaelcfanning Nov 9, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

UnitTests

you added this to the wrong file, it should be in Shared\AssemblyInfo.cs #Closed

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed!
thanks!

s_sessionId = Guid.NewGuid().ToString();
s_telemetryConfiguration = new TelemetryConfiguration(instrumentationKey);
s_telemetryClient = new TelemetryClient(s_telemetryConfiguration);
lock (s_syncRoot)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

when we changed from single thread to multi thread, we started to create multiple configurations/clients/sessions.

With that in mind, we must synchronize the threads to prevent this behavior.


private static string s_sessionId;
private static bool s_printHeader = true;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

private static bool s_printHeader = true;

add private static ctor, all static initialization is explicit in a common place.

private readonly string sha256;
private string Sha256 => context?.Hashes?.Sha256;

private readonly int chunkSize;
private readonly string relativeFilePath;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

relativeFilePath

just retrieve this from the context as you do hashes

s_telemetryClient = telemetryClient;
s_sessionId = TelemetryEnabled ? Guid.NewGuid().ToString() : null;
ChunkSize = chunkSize;
s_telemetryConfiguration ??= telemetryConfiguration;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s_telemetryConfiguration ??= telemetryConfiguration

ensure both are null or non-null in the ctor.

@eddynaka eddynaka merged commit f4909e9 into main Nov 10, 2021
@eddynaka eddynaka deleted the users/ednakamu/create-one-session-per-run branch November 10, 2021 01:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants