-
Notifications
You must be signed in to change notification settings - Fork 4.7k
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
Fire diagnostic source events from IHostBuilder.Build #53757
Changes from 1 commit
42b36a1
ec7831b
d6cded5
1c7b509
d2b5678
99d2a77
250c87d
08729fe
e592f10
e56785a
19e412e
12ae4e9
ad5c27e
7b01d0b
f8f2a69
5625ba5
315575d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -40,7 +40,7 @@ internal sealed class HostFactoryResolver | |
return ResolveFactory<THostBuilder>(assembly, CreateHostBuilder); | ||
} | ||
|
||
public static Func<string[], object>? ResolveHostFactory(Assembly assembly, TimeSpan? waitTimeout = null, Action<object>? configureHostBuilder = null) | ||
public static Func<string[], object>? ResolveHostFactory(Assembly assembly, TimeSpan? waitTimeout = null, bool stopApplication = true, Action<object>? configureHostBuilder = null) | ||
{ | ||
if (assembly.EntryPoint is null) | ||
{ | ||
|
@@ -66,7 +66,7 @@ internal sealed class HostFactoryResolver | |
return null; | ||
} | ||
|
||
return args => new HostingListener(args, assembly.EntryPoint, waitTimeout ?? s_defaultWaitTimeout, configureHostBuilder).CreateHost(); | ||
return args => new HostingListener(args, assembly.EntryPoint, waitTimeout ?? s_defaultWaitTimeout, stopApplication, configureHostBuilder).CreateHost(); | ||
} | ||
|
||
private static Func<string[], T>? ResolveFactory<T>(Assembly assembly, string name) | ||
|
@@ -166,16 +166,18 @@ private class HostingListener : IObserver<DiagnosticListener>, IObserver<KeyValu | |
private readonly string[] _args; | ||
private readonly MethodInfo _entryPoint; | ||
private readonly TimeSpan _waitTimeout; | ||
private readonly bool _stopApplication; | ||
|
||
private readonly TaskCompletionSource<object> _hostTcs = new(); | ||
private IDisposable? _disposable; | ||
private Action<object>? _configure; | ||
|
||
public HostingListener(string[] args, MethodInfo entryPoint, TimeSpan waitTimeout, Action<object>? configure) | ||
public HostingListener(string[] args, MethodInfo entryPoint, TimeSpan waitTimeout, bool stopApplication, Action<object>? configure) | ||
{ | ||
_args = args; | ||
_entryPoint = entryPoint; | ||
_waitTimeout = waitTimeout; | ||
_stopApplication = stopApplication; | ||
_configure = configure; | ||
} | ||
|
||
|
@@ -273,8 +275,11 @@ public void OnNext(KeyValuePair<string, object?> value) | |
{ | ||
_hostTcs.TrySetResult(value.Value!); | ||
|
||
// Stop the host from running further | ||
throw new StopTheHostException(); | ||
if (_stopApplication) | ||
{ | ||
// Stop the host from running further | ||
throw new StopTheHostException(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The prize for dirty hackery this week : D Is it important to guarantee that the thread really does stop? It would be easy enough for an app to throw a try/catch around the part of their code where this gets raised so that it never gets back to the entrypoint. Your tool code will be running in parallel with the user's unknown error handling app code. It doesn't seem obviously harmful to me but figured I mention it. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Disposal is one of the things I'm worried about and why I think throwing to stop execution makes the most sense here. The main app never gets a handle on the application here. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The thing that stops this from happening in the throw case is the fact that the application never gets access to the IHost instance. They can't call build again on it because double building throws. Even if they catch the exception and do something else, the IHost isntance that came out of Build is never observed by the application. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, I wasn't imagining they continue normally, more like they have some complex error handling code that will be running in parallel.
[Joking] What do you mean? This PR just added the official mechanism that lets everyone access IHost without the pesky inconvenience of needing Build() to return it to you ;p |
||
} | ||
} | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see a test that uses
configureHostBuilder
. Do we need this parameter?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, we will need it for https://github.com/dotnet/aspnetcore/blob/main/src/Mvc/Mvc.Testing/src/WebApplicationFactory.cs
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, then it would be great if we had a test ensuring it doesn't break.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
2 things: