| File: NativeDiagnosticPump.cs | Web Access |
| Project: src\src\Aspire.Hosting.Native.Server\Aspire.Hosting.Native.Server.csproj (Aspire.Hosting.Native.Server) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using Aspire.Hosting.Native.Diagnostics; namespace Aspire.Hosting.Native.Server; /// <summary>Consumes one independent channel off the operation producer and drains on shutdown.</summary> internal sealed class NativeDiagnosticPump : IAsyncDisposable { private readonly OperationEventSubscription _subscription; private readonly Task _consumer; private readonly NativeServerOptions _options; public NativeDiagnosticPump(Action<OperationEvent> consume, Action<Exception> error, NativeServerOptions options) { options.Validate(); _options = options; _subscription = NativeDiagnostics.Events.Subscribe(); _consumer = Task.Run(async () => { try { await foreach (var operation in _subscription.Reader.ReadAllAsync().ConfigureAwait(false)) { consume(operation); } } catch (Exception exception) { // Subscriber failures are isolated from host operations, and the // queue completes even when the consumer itself fails. _subscription.Dispose(); error(exception); } }); } public async ValueTask DisposeAsync() { _subscription.Dispose(); // A redirected stderr pipe may stop draining. It must not keep host // teardown alive indefinitely after its bounded subscription completes. await _consumer.WaitAsync(_options.CleanupTimeout, _options.TimeProvider).ConfigureAwait(false); } }