API server: creating an Executable hangs 30-45 s (504) while the log storage restarts its parent resource watcher for Executables
Los mantenedores suelen responder en 1 día
@danegsta ya está trabajando en esto.
Desde el 10/10/2026.
Evaluación
- Dificultad
- 4/5
- Tiempo estimado
- 3-5 días
- Aptitud para principiantes
- 45/100
Línea de trabajo
Start in api/v1/log_storage.go, especially the 30-second watcher restart loop, ls.mutex, and stopWatcher. Reproduce or inspect the macOS timing from the attached start-apiserver logs, then determine what Stop waits for and whether a blocked watcher can stall an unrelated Executable create. Done means the blocking behavior is explained and covered by an appropriate regression check.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
Summary
On GitHub-hosted macOS runners, creating an Executable via the API server hangs until the server's own request timeout (HTTP 504 Timeout: request did not complete within requested timeout - context deadline exceeded). In both occurrences, the log storage's periodic restart of its parent resource watcher for Executable (log_storage.go, every 30 s) was stuck at "Stopping old parent resource watcher…" for the whole time, and only completed when the client (Aspire AppHost) disconnected. We could not reproduce it on Windows, where the same restart completes in the same millisecond.
I don't know the root cause. I'm reporting what the logs show in case it is a known problem or the maintainers can tell what Stop waits for.
Environment
- DCP 0.26.4 (commit
182c961ce6b2f6b23e785d2963a500d1ed65291d, built 2026-09-24), shipped with Aspire 13.6.0 (Aspire.Hosting.Orchestration.osx-x64) - GitHub-hosted
macos-15-intelrunner (public runners; no nested virtualization), Docker 29.8.2 in a Lima 2.2.0 VM (QEMU software emulation, 2 CPUs, 6 GB) as the container runtime. Everything is very slow there: image pulls take 3+ minutes, MySQL initialization 2-3 more. - Client: Aspire AppHost started from
DistributedApplicationTestingBuilder(integration tests),DCP_DIAGNOSTICS_LOG_LEVEL=debug - Not tested with DCP 0.26.5 (Aspire
release/13.6moved to it in microsoft/aspire#20636, which changes concurrency of same-kind mutations; possibly relevant)
What happens
The Aspire AppHost has a MySQL container, three project services (each waits for its own database in that container) and a web frontend project that waits for the three services, so the frontend's Executable is created some time after the services' executables. The AppHost requests log streams for every executable it observes.
| Run A | Run B | |
|---|---|---|
| Services' executables started | 11:23:07 | 12:57:37 |
| First log stream requested for them | ~11:23:07 | 12:57:37 |
Log storage logs Restarting parent resource watcher… (Kind=Executable) |
11:23:37.889 (+30 s) | 12:58:07.381 (+30 s) |
…Stopping old parent resource watcher… |
11:23:37.889 | 12:58:07.382 |
Frontend Executable create request sent |
~11:23:49 | 12:58:18 |
| Create fails | 11:24:09.9 (client timed out after 20 s; server logged Timeout or abort while handling at 11:24:09.908) |
12:58:52.8 (HTTP 504 from the API server, about 34 s after the request) |
…Old parent resource watcher stopped |
11:24:10.865 (33 s later) | 12:58:53.616 (46 s later) |
…Creating new parent resource watcher… |
11:24:10.866 | 12:58:53.618 |
In both runs the "stopped" line appears within about a second of the AppHost tearing down its connections (the Context was canceled, closing log stream / Log streaming for resource completed messages, and in run B the API server switching to CleaningResources at 12:58:53.025). So, for as long as the AppHost kept its connections open, the Stop did not return, and the Executable create was stuck behind it. The controller log has no entry at all for the frontend executable during that window, so the create never got past the API server.
Relevant excerpt (run B, start-apiserver log):
12:58:07.381Z Restarting parent resource watcher... Kind=usvc-dev.developer.microsoft.com/v1, Kind=Executable
12:58:07.382Z Stopping old parent resource watcher... Kind=usvc-dev.developer.microsoft.com/v1, Kind=Executable
... nothing for Kind=Executable ...
12:58:53.616Z Old parent resource watcher stopped Kind=usvc-dev.developer.microsoft.com/v1, Kind=Executable
During the same period the restarts for Kind=Container complete immediately (14 times in run B, each Stopping / stopped in the same millisecond).
Where I think it is
api/v1/log_storage.go: the restart loop (watcherRestartInterval = 30 * time.Second) takes ls.mutex, then calls stopWatcher(ls.watcher) before creating the new watcher, and its comment says the stop has to come first to avoid a deadlock between delivering a watch event and creating a new watcher (watch set lock in shared vs. exclusive mode). If Stop waits for the watch set lock while some event delivery is blocked (for example on a slow or non-reading watch/log-stream consumer), the exclusive lock request would also block new shared acquisitions, which could explain why an unrelated Executable create stalls. That is a guess based on reading the code, not something I verified.
Why only macOS CI (probably)
On Windows, with the same AppHost shape, the restart completes in the same millisecond and the frontend is created 6 s later without problems (15:17:26.456 Restarting/Stopping/stopped right after the log streams started at 15:16:56, 30 s earlier). On the GitHub macOS runners the services take 30+ s to become healthy and the machine is heavily loaded, so the frontend create lands inside the window. Of the four macOS runs of this AppHost where the watcher problem in microsoft/aspire#20609 was worked around (so that executables were observed at all), two failed this way and two passed. In both passing runs the frontend was created 8-12 s after the services, before the first restart. In a later CI run, five other AppHosts of the same shape (PostgreSQL, RabbitMQ, Valkey, a service-discovery sample and MySQL again) all created their last project 6-12 s after the first ones, and in all of them the 30 s restart of the Executable watcher completed in the same millisecond. So the failures correlate with the last project being created more than 30 s after the first executable, which happens when the services take longer to become healthy on a loaded runner.
Expected behavior
Stop of the old parent watcher should not block unrelated API operations (creates) on the same kind, or at least not for tens of seconds.
Questions
- Is this known, and is it possibly addressed by DCP 0.26.5?
- What does
Stopwait for here, and is there a log level or diagnostic switch that would show it? - Is a 30 s restart of the parent watcher still needed (the comment says it mitigates missed events)?
Related
- microsoft/aspire#20609 (Aspire's own watches dying after 60 s; the reason these DCP logs became visible, because executables are only observed now)
I attached the relevant excerpt of the start-apiserver log from run B (dcp-apiserver-excerpt-run-b.log). The complete DCP diagnostic logs (start-apiserver and run-controllers, DCP_DIAGNOSTICS_LOG_LEVEL=debug) for both runs can be provided if useful.
- Lenguaje dominante
- Go
- Estrellas
- 191
- Forks
- 27
- Merge medio
- 2 d 9 h
- PR fusionados (30 d)
- 16
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
- Sin 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 microsoft/dcp
-
ContainerVolume stuck in PendingAbierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 76/100
Los mantenedores suelen responder en 1 día
-
Add application iconAbierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100
Los mantenedores suelen responder en 1 día
-
WSLC orchestrator: error classification relies on English CLI messages, breaks on localized Windows (volumes never created, containers never start)Posiblemente ocupada @danegsta la tomó hace 2 días. Abierto
Dificultad 3/5 1-2 días Aptitud para principiantes 52/100
Los mantenedores suelen responder en 1 día
-
Dificultad 5/5 Más de una semana Aptitud para principiantes 35/100
Los mantenedores suelen responder en 1 día
-
Dificultad 4/5 3-5 días Aptitud para principiantes 48/100
Los mantenedores suelen responder en 1 día
Todos los issues de microsoft/dcp
Issues similares
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 75/100
github/github-mcp-server#3581 ·
Los mantenedores suelen responder en 2 días
-
agent-review-finding chore
Dificultad 1/5 Menos de una hora Aptitud para principiantes 85/100
jordansmall/spindrift#6033 ·
Los mantenedores suelen responder en 1 día
-
Replace UUID implementationAbiertoenhancement
Dificultad 2/5 1-3 horas Aptitud para principiantes 75/100
hyperledger/fabric-x-common#230 ·
Los mantenedores suelen responder en 1 día
-
About.md no longer usedAbiertobug
Dificultad 2/5 Medio día Aptitud para principiantes 65/100
open-wanderer/wanderer#1443 · 3 comentarios ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 75/100
Los mantenedores suelen responder en 1 día