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

Add IHostedLifecycleService #87335

Merged
merged 5 commits into from
Jun 30, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,13 @@ public partial interface IHostBuilder
Microsoft.Extensions.Hosting.IHostBuilder UseServiceProviderFactory<TContainerBuilder>(Microsoft.Extensions.DependencyInjection.IServiceProviderFactory<TContainerBuilder> factory) where TContainerBuilder : notnull;
Microsoft.Extensions.Hosting.IHostBuilder UseServiceProviderFactory<TContainerBuilder>(System.Func<Microsoft.Extensions.Hosting.HostBuilderContext, Microsoft.Extensions.DependencyInjection.IServiceProviderFactory<TContainerBuilder>> factory) where TContainerBuilder : notnull;
}
public partial interface IHostedLifecycleService : Microsoft.Extensions.Hosting.IHostedService
{
System.Threading.Tasks.Task StartedAsync(System.Threading.CancellationToken cancellationToken);
System.Threading.Tasks.Task StartingAsync(System.Threading.CancellationToken cancellationToken);
System.Threading.Tasks.Task StoppedAsync(System.Threading.CancellationToken cancellationToken);
System.Threading.Tasks.Task StoppingAsync(System.Threading.CancellationToken cancellationToken);
}
public partial interface IHostedService
{
System.Threading.Tasks.Task StartAsync(System.Threading.CancellationToken cancellationToken);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Threading.Tasks;
using System.Threading;

namespace Microsoft.Extensions.Hosting
{
/// <summary>
/// Defines methods that are run before or after
/// <see cref="IHostedService.StartAsync(CancellationToken)"/> and
/// <see cref="IHostedService.StopAsync(CancellationToken)"/>.
/// </summary>
public interface IHostedLifecycleService : IHostedService
{
/// <summary>
/// Triggered before <see cref="IHostedService.StartAsync(CancellationToken)"/>.
/// </summary>
/// <param name="cancellationToken">Indicates that the start process has been aborted.</param>
/// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
Task StartingAsync(CancellationToken cancellationToken);

/// <summary>
/// Triggered after <see cref="IHostedService.StartAsync(CancellationToken)"/>.
/// </summary>
/// <param name="cancellationToken">Indicates that the start process has been aborted.</param>
/// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
Task StartedAsync(CancellationToken cancellationToken);

/// <summary>
/// Triggered before <see cref="IHostedService.StopAsync(CancellationToken)"/>.
/// </summary>
/// <param name="cancellationToken">Indicates that the start process has been aborted.</param>
/// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
Task StoppingAsync(CancellationToken cancellationToken);

/// <summary>
/// Triggered after <see cref="IHostedService.StopAsync(CancellationToken)"/>.
/// </summary>
/// <param name="cancellationToken">Indicates that the stop process has been aborted.</param>
/// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
Task StoppedAsync(CancellationToken cancellationToken);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ public HostOptions() { }
public bool ServicesStartConcurrently { get { throw null; } set { } }
public bool ServicesStopConcurrently { get { throw null; } set { } }
public System.TimeSpan ShutdownTimeout { get { throw null; } set { } }
public System.TimeSpan StartupTimeout { get { throw null; } set { } }
}
}
namespace Microsoft.Extensions.Hosting.Internal
Expand Down
25 changes: 24 additions & 1 deletion src/libraries/Microsoft.Extensions.Hosting/src/HostOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

using System;
using System.Globalization;
using System.Threading;
using Microsoft.Extensions.Configuration;

namespace Microsoft.Extensions.Hosting
Expand All @@ -13,10 +14,25 @@ namespace Microsoft.Extensions.Hosting
public class HostOptions
{
/// <summary>
/// The default timeout for <see cref="IHost.StopAsync(System.Threading.CancellationToken)"/>.
/// The default timeout for <see cref="IHost.StopAsync(CancellationToken)"/>.
/// </summary>
/// <remarks>
/// This timeout also encompasses all host services implementing
/// <see cref="IHostedLifecycleService.StoppingAsync(CancellationToken)"/> and
/// <see cref="IHostedLifecycleService.StoppedAsync(CancellationToken)"/>.
/// </remarks>
public TimeSpan ShutdownTimeout { get; set; } = TimeSpan.FromSeconds(30);

/// <summary>
/// The default timeout for <see cref="IHost.StartAsync(CancellationToken)"/>.
/// </summary>
/// <remarks>
/// This timeout also encompasses all host services implementing
/// <see cref="IHostedLifecycleService.StartingAsync(CancellationToken)"/> and
/// <see cref="IHostedLifecycleService.StartedAsync(CancellationToken)"/>.
/// </remarks>
public TimeSpan StartupTimeout { get; set; } = Timeout.InfiniteTimeSpan;

/// <summary>
/// Determines if the <see cref="IHost"/> will start registered instances of <see cref="IHostedService"/> concurrently or sequentially. Defaults to false.
/// </summary>
Expand Down Expand Up @@ -46,6 +62,13 @@ internal void Initialize(IConfiguration configuration)
ShutdownTimeout = TimeSpan.FromSeconds(seconds);
}

timeoutSeconds = configuration["startupTimeoutSeconds"];
steveharter marked this conversation as resolved.
Show resolved Hide resolved
if (!string.IsNullOrEmpty(timeoutSeconds)
&& int.TryParse(timeoutSeconds, NumberStyles.None, CultureInfo.InvariantCulture, out seconds))
{
StartupTimeout = TimeSpan.FromSeconds(seconds);
}

var servicesStartConcurrently = configuration["servicesStartConcurrently"];
if (!string.IsNullOrEmpty(servicesStartConcurrently)
&& bool.TryParse(servicesStartConcurrently, out bool startBehavior))
Expand Down
Loading
Loading