@@ -18,11 +18,6 @@ internal class SpaProxyLaunchManager : IHostedService, IDisposable
1818 {
1919 private readonly SpaDevelopmentServerOptions _options ;
2020 private readonly ILogger < SpaProxyLaunchManager > _logger ;
21- private readonly HttpClient _httpClient = new ( new HttpClientHandler ( )
22- {
23- // It's ok for us to do this here since this service is only plugged in during development.
24- ServerCertificateCustomValidationCallback = HttpClientHandler . DangerousAcceptAnyServerCertificateValidator
25- } ) ;
2621
2722 private Process ? _spaProcess ;
2823 private bool _disposedValue ;
@@ -39,50 +34,63 @@ public SpaProxyLaunchManager(ILogger<SpaProxyLaunchManager> logger)
3934
4035 public async Task StartAsync ( CancellationToken cancellationToken )
4136 {
37+ var httpClient = new HttpClient ( new HttpClientHandler ( )
38+ {
39+ // It's ok for us to do this here since this service is only plugged in during development.
40+ ServerCertificateCustomValidationCallback = HttpClientHandler . DangerousAcceptAnyServerCertificateValidator
41+ } ) ;
42+
4243 _logger . LogInformation ( "Starting SPA development server" ) ;
43- var running = await ProbeSpaDevelopmentServerUrl ( cancellationToken ) ;
44+ var running = await ProbeSpaDevelopmentServerUrl ( httpClient , cancellationToken ) ;
4445 if ( running )
4546 {
4647 _logger . LogInformation ( $ "Found SPA development server running at { _options . ServerUrl } ") ;
4748 }
4849 else
4950 {
5051 _logger . LogInformation ( $ "No SPA development server running at { _options . ServerUrl } found.") ;
51- await StartSpaProcessAndProbeForLiveness ( cancellationToken ) ;
52+ await StartSpaProcessAndProbeForLiveness ( httpClient , cancellationToken ) ;
5253 }
5354 }
5455
55- private async Task < bool > ProbeSpaDevelopmentServerUrl ( CancellationToken cancellationToken )
56+ private async Task < bool > ProbeSpaDevelopmentServerUrl ( HttpClient httpClient , CancellationToken cancellationToken )
5657 {
58+ using var timeout = new CancellationTokenSource ( 1000 ) ;
59+ using var cancellationTokenSource = CancellationTokenSource . CreateLinkedTokenSource ( timeout . Token , cancellationToken ) ;
5760 try
5861 {
59- var response = await _httpClient . GetAsync ( _options . ServerUrl , cancellationToken ) ;
62+ var response = await httpClient . GetAsync ( _options . ServerUrl , cancellationTokenSource . Token ) ;
6063 var running = response . IsSuccessStatusCode ;
6164 return running ;
6265 }
63- catch ( HttpRequestException httpException )
66+ catch ( Exception exception ) when ( exception is HttpRequestException || exception is TaskCanceledException )
6467 {
65- _logger . LogDebug ( httpException , "Failed to connect to the SPA Development proxy." ) ;
68+ _logger . LogDebug ( exception , "Failed to connect to the SPA Development proxy." ) ;
6669 return false ;
6770 }
6871 }
6972
70- private async Task StartSpaProcessAndProbeForLiveness ( CancellationToken cancellationToken )
73+ private async Task StartSpaProcessAndProbeForLiveness ( HttpClient httpClient , CancellationToken cancellationToken )
7174 {
7275 LaunchDevelopmentProxy ( ) ;
7376 var sw = Stopwatch . StartNew ( ) ;
7477 var livenessProbeSucceeded = false ;
7578 var maxTimeoutReached = false ;
76- while ( _spaProcess != null && ! _spaProcess . HasExited && ! livenessProbeSucceeded && ! maxTimeoutReached )
79+ while ( _spaProcess != null && ! _spaProcess . HasExited && ! maxTimeoutReached )
7780 {
78- livenessProbeSucceeded = await ProbeSpaDevelopmentServerUrl ( cancellationToken ) ;
81+ livenessProbeSucceeded = await ProbeSpaDevelopmentServerUrl ( httpClient , cancellationToken ) ;
7982 if ( livenessProbeSucceeded )
8083 {
8184 break ;
8285 }
8386
87+ if ( cancellationToken . IsCancellationRequested )
88+ {
89+ return ;
90+ }
91+
8492 maxTimeoutReached = sw . Elapsed >= _options . MaxTimeout ;
85- await Task . Delay ( 1000 ) ;
93+ await Task . Delay ( 1000 , cancellationToken ) ;
8694 }
8795
8896 if ( _spaProcess == null || _spaProcess . HasExited )
0 commit comments