dotnet / dotnet/aspnetcore

Restarting during dotnet-watch with hot reload doesn't remove unix domain socket

Open
#47,310 16 comments 2 reactions 0 assignees View on GitHub
area-networking feature-hot-reload
Dominant language
C#
Stars
38.4k
Forks
10.9k
Avg merge
2d 10h
Merged PRs (30d)
281

Description

### Is there an existing issue for this?

- [X] I have searched the existing issues

### Describe the bug

When I run an asp core project with `dotnet watch` with hot reload, and then use `ctrl + r` to restart the app, the unix domain socket is not removed during the app shutdown. Then, when the app starts again, kestrel fails to establish itself on the unix domain socket.

I'm using dotnet 7 on an m1, macos 13.2.1.

### Expected Behavior

Given an instruction to `dotnet watch` to restart the app; when kestrel shuts down; then the unix domain socket should be removed.

### Steps To Reproduce

[Minimal repro project!](https://github.com/djeikyb/repro-net7-hot-reload-unix-domain-socket) Used 7.0.202 with the webapi template, and a workaround with logging. The logs demonstrate that the unix domain socket still exists. But since we're checking anyway, I remove the socket so that kestrel won't be bothered by it.

```
var builder = WebApplication.CreateBuilder(args);

var socketPath = Path.Combine(Path.GetTempPath(), "jacob-webapi");

builder.WebHost.ConfigureKestrel(
kestrel =>
{
kestrel.ListenLocalhost(5277);
kestrel.ListenUnixSocket(
socketPath,
listen =>
{
var logger = listen.ApplicationServices.GetRequiredService>();
if (File.Exists(socketPath))
{
logger.LogInformation("Our Unix Domain Socket already exists at {UdsPath}.", socketPath);
try
{
File.Delete(socketPath);
logger.LogInformation("Removed stale Unix Domain Socket at {UdsPath}.", socketPath);
}
catch (Exception e)
{
logger.LogError(
e,
"Failed to remove stale Unix Domain Socket at {UdsPath}.",
socketPath
);
}
}
}
);
}
);

builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

var app = builder.Build();
try
{
app.UseSwagger();
app.UseSwaggerUI();

var summaries = new[]
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};

app.MapGet(
"/weatherforecast",
() =>
{
var forecast = Enumerable.Range(1, 5)
.Select(
index =>
new WeatherForecast(
DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
Random.Shared.Next(-20, 57),
summaries[Random.Shared.Next(summaries.Length)]
)
)
.ToArray();
return forecast;
}
)
.WithName("GetWeatherForecast")
.WithOpenApi();

app.Run();
}
finally
{
await app.DisposeAsync();
}

record WeatherForecast(DateOnly Date, int TemperatureC, string? Summary)
{
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
}
```

### Exceptions (if any)

_No response_

### .NET Version

7.0.202

### Anything else?

_No response_

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.