codeconsole opened a new pull request, #16216:
URL: https://github.com/apache/grails-core/pull/16216

   Follow-up to #16192.
   
   ### Problem
   
   `EmbeddedMongoInitializer` hands a restart the server this JVM already 
started when the settings match the ones it was started with:
   
   ```java
   StartedServer started = discard(STARTED.get(port), settings);
   ```
   
   `EmbeddedMongoSettings.equals` compares `port`, `version`, `databaseDir` and 
`replicaSet`. **The backend is not among them**, and `StartedServer` does not 
carry it either, so nothing in the reuse path knows which backend is running.
   
   Switching `embedded.mongodb.backend` between `in-memory` and `flapdoodle` 
across a devtools restart, changing nothing else, therefore keeps the old 
server. An application that asked for a real `mongod` carries on against the 
in-memory reimplementation, which implements neither transactions, change 
streams nor `$text` — so the failure surfaces later and somewhere else, as a 
missing feature rather than a backend that was never started.
   
   Worth noting the shape of the omission: the check does compare `version`, 
which `InMemoryMongoBackend` ignores entirely. The one setting that decides 
what the server actually *is* was the one left out.
   
   ### Fix
   
   Keep the backend the server was started with alongside its settings, and 
compare it:
   
   ```java
   private record StartedServer(RunningEmbeddedMongo running, 
EmbeddedMongoSettings settings, String backend) { }
   
   if (started == null || (started.settings().equals(settings) && 
started.backend().equals(backend))) {
       return started;
   }
   ```
   
   The backend is resolved in `initialize` before the reuse question rather 
than inside `start`, since it is part of that question, and passed to `start` 
so it is selected once.
   
   `EmbeddedMongoSettings` is public API and its constructor is unchanged; the 
backend lives on the private `StartedServer` record instead.
   
   **One behaviour change worth calling out:** asking for a backend whose 
library is absent now fails even when a server is already running on that port, 
because `selectBackend` runs before the reuse check. Previously such a restart 
was silently handed the running server. The new behaviour matches what the same 
configuration does when nothing is running.
   
   ### Tests
   
   A restart that switches backend while holding version, database and replica 
set unchanged now gets a new server. The assertion is behavioural — a document 
written to the first server, then counted after the switch — because object 
identity does not distinguish the two cases here: `initialize` constructs a 
fresh `EmbeddedMongoLifecycle` on every call, reused server or not.
   
   That last point applies to the existing test beside it. **`a restart that 
asks for a different server is not handed the one already running` was 
vacuous**: I removed `version` from `EmbeddedMongoSettings.equals` and it still 
passed, so it was not verifying replacement at all. It is rewritten here with 
the same behavioural assertion, and now fails when `version` is removed from 
the comparison.
   
   Both tests fail on unmodified `8.0.x` and pass with the fix; 
`:grails-data-mongodb-embedded:test` is green.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to