Skip to content

Commit

Permalink
Merge branch 'master' into DisposeLeaks
Browse files Browse the repository at this point in the history
  • Loading branch information
HolyPrapor committed Oct 7, 2021
2 parents 8f45baa + db2a090 commit 1a0a10d
Show file tree
Hide file tree
Showing 12 changed files with 146 additions and 42 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
## 0.3.27 (01-10-2021):

- Added `DiagnosticMetricsEnabled` settings
- Fixed #60

## 0.3.26 (16-09-2021):

Add possibility to target setup of host metrics.
Expand Down
6 changes: 2 additions & 4 deletions Vostok.Hosting.Tests/VostokHost_Tests_Dispose.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,11 @@ public void Should_not_block_on_dispose_longer_than_shutdown_timeout_allows()

var host = new VostokHost(new TestHostSettings(app, SetupEnvironment));

host.Start();

var watch = Stopwatch.StartNew();

host.Stop().State.Should().Be(VostokApplicationState.Exited);
host.Run().State.Should().Be(VostokApplicationState.Exited);

watch.Elapsed.Should().BeLessThan(2.Seconds());
watch.Elapsed.Should().BeLessThan(5.Seconds());
}

private static void SetupEnvironment(IVostokHostingEnvironmentBuilder builder)
Expand Down
109 changes: 85 additions & 24 deletions Vostok.Hosting.Tests/VostokHostingEnvironmentFactory_Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using Vostok.Hosting.Components.Shutdown;
using Vostok.Hosting.Components.ZooKeeper;
using Vostok.Hosting.Setup;
using Vostok.Metrics;
using Vostok.Metrics.System.Gc;
using Vostok.Metrics.System.Process;

Expand All @@ -30,7 +31,7 @@ public void TestSetup()
public void Should_produce_an_environment_with_linked_cancellation_tokens()
{
var environment = VostokHostingEnvironmentFactory.Create(Setup);

shutdown.Cancel();

Action assertion = () => environment.ShutdownToken.IsCancellationRequested.Should().BeTrue();
Expand All @@ -55,42 +56,47 @@ public void Should_produce_an_environment_with_ticking_shutdown_budget_upon_canc

var immediatelyAfter = environment.ShutdownTimeout;

Thread.Sleep(100);

var awhileAfter = environment.ShutdownTimeout;

awhileAfter.Should().BeLessThan(immediatelyAfter);
new Action(() =>
{
environment.ShutdownTimeout.Should().BeLessThan(immediatelyAfter);
}).ShouldPassIn(5.Seconds());
}

[Test]
public void Should_substract_beacon_shutdown_timeout_from_total()
{
var environment = VostokHostingEnvironmentFactory.Create(SetupWithServiceDiscovery, new VostokHostingEnvironmentFactorySettings
{
BeaconShutdownTimeout = 3.Seconds()
});
var environment = VostokHostingEnvironmentFactory.Create(
SetupWithServiceDiscovery,
new VostokHostingEnvironmentFactorySettings
{
BeaconShutdownTimeout = 3.Seconds()
});

environment.ShutdownTimeout.Should().Be(27.Seconds());
}

[Test]
public void Should_not_substract_beacon_shutdown_timeout_from_total_if_there_is_no_real_beacon()
{
var environment = VostokHostingEnvironmentFactory.Create(Setup, new VostokHostingEnvironmentFactorySettings
{
BeaconShutdownTimeout = 3.Seconds()
});
var environment = VostokHostingEnvironmentFactory.Create(
Setup,
new VostokHostingEnvironmentFactorySettings
{
BeaconShutdownTimeout = 3.Seconds()
});

environment.ShutdownTimeout.Should().Be(30.Seconds());
}

[Test]
public void Should_wait_after_beacon_shutdown_if_instructed_to_do_so()
{
var environment = VostokHostingEnvironmentFactory.Create(SetupWithServiceDiscovery, new VostokHostingEnvironmentFactorySettings
{
BeaconShutdownTimeout = 1.Seconds()
});
var environment = VostokHostingEnvironmentFactory.Create(
SetupWithServiceDiscovery,
new VostokHostingEnvironmentFactorySettings
{
BeaconShutdownTimeout = 1.Seconds()
});

var watch = Stopwatch.StartNew();

Expand All @@ -104,11 +110,13 @@ public void Should_wait_after_beacon_shutdown_if_instructed_to_do_so()
[Test]
public void Should_not_wait_after_beacon_shutdown_if_disabled()
{
var environment = VostokHostingEnvironmentFactory.Create(SetupWithServiceDiscovery, new VostokHostingEnvironmentFactorySettings
{
BeaconShutdownTimeout = 2.Seconds(),
BeaconShutdownWaitEnabled = false
});
var environment = VostokHostingEnvironmentFactory.Create(
SetupWithServiceDiscovery,
new VostokHostingEnvironmentFactorySettings
{
BeaconShutdownTimeout = 2.Seconds(),
BeaconShutdownWaitEnabled = false
});

var watch = Stopwatch.StartNew();

Expand Down Expand Up @@ -142,6 +150,59 @@ public void Should_provide_system_metrics_extensions()
environment.HostExtensions.TryGet<CurrentProcessMonitor>(out _).Should().BeTrue();
}

[Test]
public void Should_provide_dev_null_metric_context_when_diagnostic_metrics_disabled_and_no_senders()
{
var environment = VostokHostingEnvironmentFactory.Create(Setup, new VostokHostingEnvironmentFactorySettings
{
DiagnosticMetricsEnabled = false
});

environment.Metrics.Root.Should().BeOfType<DevNullMetricContext>();
}

[Test]
public void Should_provide_dev_null_metric_context_when_no_metric_event_senders_built()
{
var environment = VostokHostingEnvironmentFactory.Create(SetupForDevNullMetricContext, new VostokHostingEnvironmentFactorySettings());

environment.Metrics.Root.Should().BeOfType<DevNullMetricContext>();

void SetupForDevNullMetricContext(IVostokHostingEnvironmentBuilder builder)
{
Setup(builder);
builder.SetupDiagnostics(x => x.CustomizeInfo(s => s.AddApplicationMetricsInfo = false)); // disable ApplicationMetricsProvider metrics sender
}
}

[Test]
public void Should_provide_not_dev_null_metric_context_when_metric_event_senders_built()
{
var environment = VostokHostingEnvironmentFactory.Create(SetupForDevNullMetricContext, new VostokHostingEnvironmentFactorySettings());

environment.Metrics.Root.Should().BeOfType<MetricContext>();

void SetupForDevNullMetricContext(IVostokHostingEnvironmentBuilder builder)
{
Setup(builder);
builder.SetupDiagnostics(x => x.CustomizeInfo(s => s.AddApplicationMetricsInfo = true)); // enable ApplicationMetricsProvider metrics sender
}
}

[Test, Explicit]
public void Should_not_leak()
{
for (int i = 0; i < 100; i++)
{
var environment = VostokHostingEnvironmentFactory.Create(Setup,
new VostokHostingEnvironmentFactorySettings
{
ConfigureStaticProviders = false
});
(environment as IDisposable)?.Dispose();
}
}

private void Setup(IVostokHostingEnvironmentBuilder builder)
{
builder.DisableClusterConfig();
Expand Down Expand Up @@ -178,4 +239,4 @@ private void SetupCommons(IVostokHostingEnvironmentBuilder builder)
builder.SetupLog(log => log.SetupConsoleLog());
}
}
}
}
23 changes: 15 additions & 8 deletions Vostok.Hosting/Components/Environment/EnvironmentBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ private VostokHostingEnvironment BuildInner(BuildContext context)
context.SecretConfigurationProvider) = configurationBuilder.Build(context);
}

if (settings.ConfigureStaticProviders && context.ConfigurationProvider is ConfigurationProvider configProvider)
if (settings.ConfigureStaticProviders && context.ConfigurationProvider is {} configProvider)
ConfigurationProvider.TrySetDefault(configProvider);

context.EnvironmentSetupContext = new EnvironmentSetupContext(
Expand Down Expand Up @@ -188,7 +188,7 @@ private VostokHostingEnvironment BuildInner(BuildContext context)

context.SubstituteTracer(tracerBuilder.Build(context));

if (diagnosticsBuilder.Builder.NeedsApplicationMetricsProvider)
if (settings.DiagnosticMetricsEnabled && diagnosticsBuilder.GetIntermediateBuilder(context).NeedsApplicationMetricsProvider)
{
context.MetricsInfoProvider = new ApplicationMetricsProvider();
metricsBuilder.AddCustomization(metrics => metrics.AddMetricEventSender(context.MetricsInfoProvider));
Expand All @@ -201,7 +201,8 @@ private VostokHostingEnvironment BuildInner(BuildContext context)
if (settings.SendAnnotations)
AnnotationsHelper.ReportLaunching(context.ApplicationIdentity, context.Metrics.Instance);

context.RegisterDisposable(HerculesSinkMetrics.Measure(context.HerculesSink, context.Metrics, context.Log));
if (settings.DiagnosticMetricsEnabled)
context.RegisterDisposable(HerculesSinkMetrics.Measure(context.HerculesSink, context.Metrics, context.Log));

if (settings.ConfigureStaticProviders)
FlowingContext.Configuration.ErrorCallback = (errorMessage, error) => context.Log.ForContext(typeof(FlowingContext)).Error(error, errorMessage);
Expand All @@ -218,7 +219,9 @@ private VostokHostingEnvironment BuildInner(BuildContext context)
context.ConfigurationSource.SwitchTo(src => src.Substitute(configSubstitutions));
context.SecretConfigurationSource.SwitchTo(src => src.Substitute(configSubstitutions));

context.DiagnosticsHub = diagnosticsBuilder.Build(context);
context.DiagnosticsHub = settings.DiagnosticMetricsEnabled
? diagnosticsBuilder.Build(context)
: new DiagnosticsHub(new DiagnosticInfo(), new HealthTracker(TimeSpan.MaxValue, context.Log));

var (hostingShutdown, applicationShutdown) = ShutdownFactory.Create(
context.ServiceBeacon,
Expand Down Expand Up @@ -261,7 +264,8 @@ private VostokHostingEnvironment BuildInner(BuildContext context)

hostExtensionsBuilder.Build(context, vostokHostingEnvironment);

systemMetricsBuilder.Build(context, vostokHostingEnvironment);
if (settings.DiagnosticMetricsEnabled)
systemMetricsBuilder.Build(context, vostokHostingEnvironment);

if (!hasLogs)
{
Expand All @@ -270,14 +274,17 @@ private VostokHostingEnvironment BuildInner(BuildContext context)
context.Log = context.Logs.BuildCompositeLog(out _);
}

context.RegisterDisposable(LogLevelMetrics.Measure(context.Logs.LogEventLevelCounterFactory.CreateCounter(), context.Metrics));
if (settings.DiagnosticMetricsEnabled)
context.RegisterDisposable(LogLevelMetrics.Measure(context.Logs.LogEventLevelCounterFactory.CreateCounter(), context.Metrics));

if (settings.ConfigureStaticProviders)
StaticProvidersHelper.Configure(vostokHostingEnvironment);

context.DiagnosticsHub.HealthTracker.LaunchPeriodicalChecks(vostokHostingEnvironment.ShutdownToken);
if (settings.DiagnosticMetricsEnabled)
context.DiagnosticsHub.HealthTracker.LaunchPeriodicalChecks(vostokHostingEnvironment.ShutdownToken);

context.RegisterDisposable(HealthCheckMetrics.Measure(context.DiagnosticsHub.HealthTracker, context.Metrics));
if (settings.DiagnosticMetricsEnabled)
context.RegisterDisposable(HealthCheckMetrics.Measure(context.DiagnosticsHub.HealthTracker, context.Metrics));

return vostokHostingEnvironment;
}
Expand Down
20 changes: 17 additions & 3 deletions Vostok.Hosting/Helpers/CustomizableBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ internal class CustomizableBuilder<TBuilder, TResult>
{
private readonly TBuilder builder;
private readonly Customization<TBuilder> builderCustomization;

private volatile IVostokHostingEnvironmentSetupContext environmentSetupContext;
private volatile IVostokConfigurationSetupContext configurationSetupContext;

Expand All @@ -20,8 +20,6 @@ public CustomizableBuilder(TBuilder builder)
builderCustomization = new Customization<TBuilder>();
}

public TBuilder Builder => builder;

public void AddCustomization(Action<TBuilder> setup)
=> builderCustomization.AddCustomization(setup);

Expand All @@ -40,5 +38,21 @@ public TResult Build(BuildContext context)

return builder.Build(context);
}

public TBuilder GetIntermediateBuilder(BuildContext context)
{
try
{
environmentSetupContext = context.EnvironmentSetupContext;
configurationSetupContext = context.ConfigurationSetupContext;

return builderCustomization.Customize(builder);
}
finally
{
environmentSetupContext = null;
configurationSetupContext = null;
}
}
}
}
3 changes: 2 additions & 1 deletion Vostok.Hosting/MultiHost/VostokMultiHost.cs
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,8 @@ private VostokHostingEnvironment SetupEnvironment()
{
var environmentFactorySettings = new VostokHostingEnvironmentFactorySettings
{
ConfigureStaticProviders = settings.ConfigureStaticProviders
ConfigureStaticProviders = settings.ConfigureStaticProviders,
DiagnosticMetricsEnabled = settings.DiagnosticMetricsEnabled
};

return EnvironmentBuilder.Build(
Expand Down
1 change: 1 addition & 0 deletions Vostok.Hosting/MultiHost/VostokMultiHostApplication.cs
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ private void CreateVostokHost(bool throwsException = true)
ConfigureStaticProviders = false,
WarmupConfiguration = false,
WarmupZooKeeper = false,
DiagnosticMetricsEnabled = false
};

vostokHost = new VostokHost(vostokHostSettings);
Expand Down
3 changes: 3 additions & 0 deletions Vostok.Hosting/MultiHost/VostokMultiHostSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,8 @@ public VostokMultiHostSettings(VostokHostingEnvironmentSetup builder)

/// <inheritdoc cref="VostokHostSettings.ThreadPoolTuningMultiplier"/>
public int ThreadPoolTuningMultiplier { get; set; } = ThreadPoolConstants.DefaultThreadPoolMultiplier;

/// <inheritdoc cref="VostokHostSettings.DiagnosticMetricsEnabled"/>
public bool DiagnosticMetricsEnabled { get; set; }
}
}
2 changes: 1 addition & 1 deletion Vostok.Hosting/Vostok.Hosting.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<LangVersion>latest</LangVersion>
</PropertyGroup>
<PropertyGroup>
<VersionPrefix>0.3.27</VersionPrefix>
<VersionPrefix>0.3.28</VersionPrefix>
</PropertyGroup>
<PropertyGroup>
<Title>Vostok.Hosting</Title>
Expand Down
3 changes: 2 additions & 1 deletion Vostok.Hosting/VostokHost.cs
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,8 @@ private VostokApplicationRunResult BuildEnvironment()
ConfigureStaticProviders = settings.ConfigureStaticProviders,
BeaconShutdownTimeout = settings.BeaconShutdownTimeout,
BeaconShutdownWaitEnabled = settings.BeaconShutdownWaitEnabled,
SendAnnotations = settings.SendAnnotations
SendAnnotations = settings.SendAnnotations,
DiagnosticMetricsEnabled = settings.DiagnosticMetricsEnabled
};

environment = EnvironmentBuilder.Build(SetupEnvironment, environmentFactorySettings);
Expand Down
10 changes: 10 additions & 0 deletions Vostok.Hosting/VostokHostSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,16 @@ public VostokHostSettings([NotNull] IVostokApplication application, [NotNull] Vo
/// If set to <c>true</c>, sends annotations with application lifecycle events (launching, initialized, stopping).
/// </summary>
public bool SendAnnotations { get; set; } = true;

/// <summary>
/// <para>If set to <c>false</c>, forcibly disables:</para>
/// <list type="bullet">
/// <item><description>All diagnostic metrics</description></item>
/// <item><description>All system metrics</description></item>
/// <item><description>All health checks</description></item>
/// </list>
/// </summary>
public bool DiagnosticMetricsEnabled { get; set; } = true;

/// <summary>
/// If enabled, <see cref="VostokHost"/> will wait for <see cref="IServiceBeacon"/> start.
Expand Down
3 changes: 3 additions & 0 deletions Vostok.Hosting/VostokHostingEnvironmentFactorySettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,8 @@ public class VostokHostingEnvironmentFactorySettings

/// <inheritdoc cref="VostokHostSettings.SendAnnotations"/>
public bool SendAnnotations { get; set; } = true;

/// <inheritdoc cref="VostokHostSettings.DiagnosticMetricsEnabled"/>
public bool DiagnosticMetricsEnabled { get; set; } = true;
}
}

0 comments on commit 1a0a10d

Please sign in to comment.