[Floci] Service Bus host ports are probed then released, so another process can take them before the Artemis sidecar binds
I maintainer di solito rispondono entro 1 giorno
Valutazione
- Difficoltà
- 4/5
- Tempo stimato
- 3-5 giorni
- Idoneità per principianti
- 20/100
- Tipo di issue
- Bug
- Chiarezza
- Specificata chiaramente
- Stato di attività
- Ferma
- Stack tecnologico
- csharp, docker
- Ambito
- backend, infrastructure
Direzione di ricerca
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.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
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
- Lingua principale
- C#
- Stelle
- 632
- Fork
- 204
- Merge medio
- 2g 13h
- PR unite (30g)
- 92
Preparare l'ambiente
Avvia il container di sviluppo del progetto nel browser, con il tuo account GitHub.
- Nessun Dockerfile né file Docker Compose
- Ha un modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di CommunityToolkit/Aspire
-
[14.0] Remove Java ResourceAperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 75/100
CommunityToolkit/Aspire#1622 · 6 commenti ·
I maintainer di solito rispondono entro 1 giorno
-
[14.0] Remove Rust resourceAperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 70/100
CommunityToolkit/Aspire#1620 · 6 commenti ·
I maintainer di solito rispondono entro 1 giorno
-
Update Toolkit to Aspire 17.1 nightly 17.1.0-preview.1.26556.8Forse già presa @aaronpowell l’ha presa 1 giorno fa. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 1/100
CommunityToolkit/Aspire#2421 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 3/5 1-2 giorni Idoneità per principianti 66/100
CommunityToolkit/Aspire#2420 ·
I maintainer di solito rispondono entro 1 giorno
-
Chroma: a Distributed setting in the client integrationForse già presa @Laurianti l’ha presa 1 giorno fa. Aperta
Difficoltà 3/5 1-2 giorni Idoneità per principianti 20/100
CommunityToolkit/Aspire#2418 ·
I maintainer di solito rispondono entro 1 giorno
Tutte le issue di CommunityToolkit/Aspire
Issue simili
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 68/100
I maintainer di solito rispondono entro 1 giorno
-
Sample solution restore fails with NU1109 (Microsoft.Extensions.Logging.Abstractions downgrade)Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 82/100
ardalis/CleanArchitecture#1150 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 82/100
reacher-z/Awesome-REA#3585 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 64/100
resend/resend-dotnet#174 ·
-
Add Vigil (BofStudios/vigil)Apertaarea:data coverage
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 68/100
reacher-z/Awesome-CUA#5039 ·
I maintainer di solito rispondono entro 19 giorni