Nothing coordinates the clone directory / registry against concurrent readers, at two points in the lifecycle.
-
No readiness gate during the initial clone. GitHubStartupInitializer.onStart kicks off the clone asynchronously and returns immediately — Quarkus finishes starting before it completes. InMemoryRegistryService starts empty, so a request during the clone window hits verifyNamespace against an empty list and gets 404 rather than 503. Class javadoc has been corrected (previously claimed a @Readiness endpoint that doesn't exist) and now points callers at GitHubCloneManager.getState(), but no gate exists.
A narrower ordering gap in the same area: GitHubCloneManager.cloneAll() sets state = READY on its last line, but registryService.rebuild(...) — the step that actually populates the registry — runs after cloneAll() returns. A gate on getState() == READY alone has the same hole: state can read READY while the registry is still empty.
-
reset --hard races with concurrent reads during periodic resync. GitHubCloneManager.pullAll() → GitHubRepoSync.pullRepo does fetch + reset --hard directly against the live clone directory, with no coordination against a request thread mid-GitHubFileReader.readContained on the same directory — can serve a torn/partial file, or a NoSuchFileException.
Fix: for 1, a filter ahead of verifyNamespace returning 503 while cloneManager.getState() is INITIALIZING/CLONING, gated on the registry actually containing the expected namespaces (not clone state alone). For 2, read/write coordination per namespace — clone into a fresh directory and atomically swap a pointer, or a read-write lock around GitHubFileReader reads. Same underlying gap; fix together.
(jpgough-ms review thread on GitHubStartupInitializer.java:68, #3066; item 2 found while building the DOMAIN_READ integration test.)
Nothing coordinates the clone directory / registry against concurrent readers, at two points in the lifecycle.
No readiness gate during the initial clone.
GitHubStartupInitializer.onStartkicks off the clone asynchronously and returns immediately — Quarkus finishes starting before it completes.InMemoryRegistryServicestarts empty, so a request during the clone window hitsverifyNamespaceagainst an empty list and gets 404 rather than 503. Class javadoc has been corrected (previously claimed a@Readinessendpoint that doesn't exist) and now points callers atGitHubCloneManager.getState(), but no gate exists.A narrower ordering gap in the same area:
GitHubCloneManager.cloneAll()setsstate = READYon its last line, butregistryService.rebuild(...)— the step that actually populates the registry — runs aftercloneAll()returns. A gate ongetState() == READYalone has the same hole: state can read READY while the registry is still empty.reset --hardraces with concurrent reads during periodic resync.GitHubCloneManager.pullAll()→GitHubRepoSync.pullRepodoesfetch+reset --harddirectly against the live clone directory, with no coordination against a request thread mid-GitHubFileReader.readContainedon the same directory — can serve a torn/partial file, or aNoSuchFileException.Fix: for 1, a filter ahead of
verifyNamespacereturning 503 whilecloneManager.getState()isINITIALIZING/CLONING, gated on the registry actually containing the expected namespaces (not clone state alone). For 2, read/write coordination per namespace — clone into a fresh directory and atomically swap a pointer, or a read-write lock aroundGitHubFileReaderreads. Same underlying gap; fix together.(jpgough-ms review thread on GitHubStartupInitializer.java:68, #3066; item 2 found while building the DOMAIN_READ integration test.)