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]