Skip to content

Commit 39e6121

Browse files
Handle @angular/cli not accept requests immediately on startup
1 parent c002937 commit 39e6121

File tree

1 file changed

+40
-3
lines changed

1 file changed

+40
-3
lines changed

src/Microsoft.AspNetCore.SpaServices.Extensions/AngularCli/AngularCliMiddleware.cs

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
using System.IO;
1111
using System.Text.RegularExpressions;
1212
using System.Threading.Tasks;
13+
using System.Threading;
14+
using System.Net.Http;
1315

1416
namespace Microsoft.AspNetCore.SpaServices.AngularCli
1517
{
@@ -89,13 +91,48 @@ private static async Task<AngularCliServerInfo> StartAngularCliServerAsync(
8991
var serverInfo = new AngularCliServerInfo { Port = uri.Port };
9092

9193
// Even after the Angular CLI claims to be listening for requests, there's a short
92-
// period where it will give an error if you make a request too quickly. Give it
93-
// a moment to finish starting up.
94-
await Task.Delay(500);
94+
// period where it will give an error if you make a request too quickly
95+
await WaitForAngularCliServerToAcceptRequests(uri);
9596

9697
return serverInfo;
9798
}
9899

100+
private static async Task WaitForAngularCliServerToAcceptRequests(Uri cliServerUri)
101+
{
102+
// To determine when it's actually ready, try making HEAD requests to '/'. If it
103+
// produces any HTTP response (even if it's 404) then it's ready. If it rejects the
104+
// connection then it's not ready.
105+
const int MaxAttempts = 10;
106+
const int SecondsBetweenAttempts = 1;
107+
108+
var attemptsMade = 0;
109+
var client = new HttpClient();
110+
111+
while (true)
112+
{
113+
try
114+
{
115+
// If we get any HTTP response, the CLI server is ready
116+
await client.SendAsync(
117+
new HttpRequestMessage(HttpMethod.Head, cliServerUri),
118+
new CancellationTokenSource(1000).Token);
119+
return;
120+
}
121+
catch (Exception ex)
122+
{
123+
attemptsMade++;
124+
if (attemptsMade >= MaxAttempts)
125+
{
126+
throw new InvalidOperationException(
127+
"Timed out waiting for the @angular/cli server to accept HTTP requests. " +
128+
"See inner exception for details.", ex);
129+
}
130+
131+
Thread.Sleep(SecondsBetweenAttempts * 1000);
132+
}
133+
}
134+
}
135+
99136
class AngularCliServerInfo
100137
{
101138
public int Port { get; set; }

0 commit comments

Comments
 (0)