Skip to content
This repository has been archived by the owner on Jun 10, 2020. It is now read-only.

Make UseAI and AddAI calls idempotent #419

Merged
merged 7 commits into from
May 3, 2017

Conversation

pakrym
Copy link
Contributor

@pakrym pakrym commented May 2, 2017

To avoid duplicated telemetries if AddApplicationInsightsTelemetry was called while UseAddApplicationInsights is in Program.Main

/cc @SergeyKanzhelev @Dmitry-Matveev @dnduffy

@pakrym
Copy link
Contributor Author

pakrym commented May 2, 2017

/cc @DamianEdwards @glennc

@DamianEdwards
Copy link
Member

This is required for the Azure light-up scenarios to work correctly and thus is needed in 2.1.0


private static bool IsApplicationInsightsAdded(IServiceCollection services)
{
// We treat ApplicationInsightsInitializer as a marker that AI services were addede to service collection
Copy link
Contributor

Choose a reason for hiding this comment

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

small typo: addede

using System.Collections.Generic;

/// <summary>
/// Class to control default debug logger and disable it if logger was added to <see cref="ILoggerFactory"/> explicetely.
Copy link
Member

Choose a reason for hiding this comment

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

typo: explicitly

Copy link
Member

Choose a reason for hiding this comment

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

Also, the description no longer makes sense for this class.

lock (callbacks)
{
foreach (var callback in callbacks)
{
Copy link
Member

@pharring pharring May 3, 2017

Choose a reason for hiding this comment

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

Should this really be in the same place where you register new loggers?
Shouldn't there be two methods: e.g. AddLoggerCallback and NotifyLoggers?
It looks like we've just re-invented a MulticastDelegate. Perhaps an event would be better?
[Edit]
OK, I see how this works now, but it's quirky. I think the doc-comments deserve a little explanation. The registered callback is called only when subsequent loggers are added.

/// <param name="factory"></param>
/// <param name="filter"></param>
/// <param name="serviceProvider">The instance of <see cref="IServiceProvider"/> to use for service resolution.</param>
/// <param name="loggerAddedCallback">The callback that get's executed when another ApplicationInsights logger is added.</param>
Copy link
Member

Choose a reason for hiding this comment

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

typo: "gets" should not have an apostrophe.

private static bool IsApplicationInsightsAdded(IServiceCollection services)
{
// We treat ApplicationInsightsInitializer as a marker that AI services were addede to service collection
return services.Any(service => service.ServiceType == typeof(ApplicationInsightsInitializer));
Copy link
Member

Choose a reason for hiding this comment

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

return services.OfType<ApplicationInsightsInitializer>().Any();

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's not what it does.

@@ -50,11 +50,27 @@ public static ILoggerFactory AddApplicationInsights(this ILoggerFactory factory,
IServiceProvider serviceProvider,
Func<string, LogLevel, bool> filter)
{
return factory.AddApplicationInsights(serviceProvider, filter, () => { });
Copy link
Member

Choose a reason for hiding this comment

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

Can't you use 'null' instead of creating an empty delegate? Then it can be a default parameter. Handle null in AddLoggerCallback with callback?.Invoke()


public ApplicationInsightsLoggerCallbacks()
{
callbacks = new List<Action>();
Copy link
Member

Choose a reason for hiding this comment

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

Could be inline with the field definition, then the constructor evaporates.

@Dmitry-Matveev
Copy link
Member

It looks like this fix will make UseAI and AddAI idempotent in the case on single-threaded execution.
Is there a way AddAI might be invoked from the several threads at the same time and still end up with two things configured because both threads will pass the check on "IsEnabled"?

@pakrym
Copy link
Contributor Author

pakrym commented May 3, 2017

@Dmitry-Matveev we are not concerned with multi threaded scenario here, configuration part of application is inherently one threaded.

Copy link
Contributor

@SergeyKanzhelev SergeyKanzhelev left a comment

Choose a reason for hiding this comment

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

thanks! It would be nice if you can also update the summary for the methods Use and Add. Mention that if you need change configuration - you need to do it before instantiating the TelemetryClient.

services.AddSingleton<ITelemetryModule, DependencyTrackingTelemetryModule>();
if (!IsApplicationInsightsAdded(services))
{
services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();
Copy link
Contributor

Choose a reason for hiding this comment

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

Does the error from this method should be traced?

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants