[Floci] Service Bus host ports are probed then released, so another process can take them before the Artemis sidecar binds
Los mantenedores suelen responder en 1 día
Evaluación
- Dificultad
- 4/5
- Tiempo estimado
- 3-5 días
- Aptitud para principiantes
- 20/100
- Tipo de issue
- Error
- Claridad
- Bien especificado
- Estado de actividad
- Estancado
- Stack tecnológico
- csharp, docker
- Área
- backend, infrastructure
Línea de trabajo
Start with FlociServiceBusEndpointAllocator and the Service Bus child resource endpoint allocation and event flow; inspect the related open pull request #2336 and the floci-az management API changes in floci-io/floci-az#592/#593. Verify that dynamically assigned host ports are discovered after floci-az starts, endpoints and connection strings become available, and explicit ports still work.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
Describe the bug
When WithServiceBus() is called without explicit ports, FlociServiceBusEndpointAllocator picks the AMQP and AMQPS host ports itself during BeforeStartEvent. It binds a probe TcpListener on each candidate port, releases the probes, and passes the ports to floci-az through FLOCI_AZ_SERVICES_SERVICE_BUS_AMQP_PORT and FLOCI_AZ_SERVICES_SERVICE_BUS_AMQP_TLS_PORT. floci-az binds them much later, when it starts the Artemis sidecar with -p <port>:5672 and -p <port>:5671.
Nothing holds the port between the release and Docker's bind. That window covers the rest of AppHost startup, the floci-az image pull, and floci-az's own boot, so it is often several seconds long. Any other process can take the port in that time: another AppHost started concurrently with --isolated, a DCP proxy, a test fixture, or anything else that binds a port. Docker then fails to start the sidecar:
failed to bind host port 0.0.0.0:<port>/tcp: address already in use
floci-az logs the failed namespace start and reports /health as DOWN, so the emulator never becomes healthy and every Service Bus consumer waits forever. Docker retries a port conflict only for dynamic (0) host ports, so an explicit preselected port cannot recover.
#2240 / #2241 moved the selection to a random port in 20000-32767 so DCP's ephemeral proxy ports no longer collide with it. That removed the most common collision, but the allocator still probes and releases, so the time-of-check/time-of-use race remains for everything else that binds ports in that range, including a second AppHost making the same random choice.
Regression
Not a regression. The probe-and-release design has been in place since the allocator was added in 13.6.0.
Steps to reproduce
The race is timing-dependent, so the simplest deterministic repro takes the selected port between allocation and the sidecar's start, as another process would:
var builder = DistributedApplication.CreateBuilder(args);
var azure = builder.AddFlociAzure("floci-az").WithDockerSocket();
var serviceBus = azure.WithServiceBus();
// Simulate another process binding the port after the integration released it.
TcpListener? squatter = null;
builder.Eventing.Subscribe<BeforeResourceStartedEvent>(azure.Resource, (_, _) =>
{
squatter ??= new TcpListener(IPAddress.Any, serviceBus.Resource.AmqpEndpoint.Port);
squatter.Start();
return Task.CompletedTask;
});
builder.Build().Run();
- Run the AppHost.
- floci-az logs that it could not start the default Service Bus namespace because Docker could not bind the host port.
floci-azstays Unhealthy, and anything that waits for it never starts.
Without the squatter, the same failure happens intermittently when several AppHosts start at the same time on one machine (for example parallel CI jobs or test fixtures), or when another local service happens to bind the selected port first.
Expected behavior
The Service Bus sidecar starts reliably regardless of what else binds ports on the machine. Only an atomic bind can guarantee that, so the host ports should be assigned by Docker, not chosen in advance by the integration:
- When the caller does not pass
amqpPort/amqpTlsPort, setFLOCI_AZ_SERVICES_SERVICE_BUS_AMQP_PORT=0andFLOCI_AZ_SERVICES_SERVICE_BUS_AMQP_TLS_PORT=0. floci-az already treats0as a dynamic Docker binding. - Leave the child's
amqp/amqpsendpoints unallocated until floci-az is ready, then read the ports Docker published from floci-az's management API (GET /{account}-servicebus/namespaces/default, fieldsamqpHostPort/amqpsHostPort), allocate the endpoints, and raiseResourceEndpointsAllocatedEventandConnectionStringAvailableEventfor the child. - Keep explicitly configured ports exactly as they are today.
Two details matter for this:
- The child currently implements
IResourceWithParent<FlociAzureContainerResource>. Aspire publishesConnectionStringAvailableEventforIResourceWithParentchildren before it creates the parent container, and resolving the connection string waits for the child's endpoints. With ports that only exist after floci-az starts, that is a deadlock. The parent-child link already exists as aWithParentRelationshipannotation, which keeps the dashboard nesting without the early resolution. - When floci-az runs in a container, its namespace API currently reports the sidecar's container-internal ports rather than the published host ports, so discovery through the API needs the new
amqpHostPort/amqpsHostPortfields from floci-io/floci-az#592 / floci-io/floci-az#593 and an image tag bump here.
Screenshots
N/A
IDE and version
Other
IDE version
Aspire CLI / Aspire.AppHost.Sdk 13.6.4
Nuget packages
CommunityToolkit.Aspire.Hosting.Floci (current main)
Image: floci/floci-az:0.15.0
Docker Desktop on Windows 11; also Linux CI runners
Additional context
Related: #2240, #2241.
Help us help you
Yes, I'd like to be assigned to work on this item
- Lenguaje dominante
- C#
- Estrellas
- 632
- Forks
- 204
- Merge medio
- 2 d 13 h
- PR fusionados (30 d)
- 92
Preparar el entorno
Inicia el contenedor de desarrollo del proyecto en tu navegador, con tu propia cuenta de GitHub.
- Sin Dockerfile ni archivo de Docker Compose
- Tiene una plantilla de pull request
- Leer la guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de CommunityToolkit/Aspire
-
[14.0] Remove Java ResourceAbierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 75/100
CommunityToolkit/Aspire#1622 · 6 comentarios ·
Los mantenedores suelen responder en 1 día
-
[14.0] Remove Rust resourceAbierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 70/100
CommunityToolkit/Aspire#1620 · 6 comentarios ·
Los mantenedores suelen responder en 1 día
-
Terraform integrationAbiertointegration request :mailbox_with_mail:
Dificultad 5/5 Más de una semana Aptitud para principiantes 35/100
CommunityToolkit/Aspire#2424 ·
Los mantenedores suelen responder en 1 día
-
Update Toolkit to Aspire 17.1 nightly 17.1.0-preview.1.26556.8Posiblemente ocupada @aaronpowell la tomó hace 2 días. Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 1/100
CommunityToolkit/Aspire#2421 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 3/5 1-2 días Aptitud para principiantes 66/100
CommunityToolkit/Aspire#2420 · 1 comentario ·
Los mantenedores suelen responder en 1 día
Todos los issues de CommunityToolkit/Aspire
Issues similares
-
area:build type:chore
Dificultad 2/5 1-3 horas Aptitud para principiantes 76/100
Los mantenedores suelen responder en 1 día
-
python triage
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
microsoft/semantic-kernel#14753 ·
Los mantenedores suelen responder en 5 días
-
NEW ISSUE Requestor-Player
Dificultad 2/5 1-3 horas Aptitud para principiantes 81/100
tModLoader/tModLoader#5575 · 1 reacción ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 82/100
Los mantenedores suelen responder en 1 día
-
A: Art Beginner Friendly P3: Standard T: Bugfix
Dificultad 2/5 1-3 horas Aptitud para principiantes 76/100
space-wizards/space-station-14#46728 ·
Los mantenedores suelen responder en 1 día