jerryshao commented on code in PR #13067:
URL: https://github.com/apache/gravitino/pull/13067#discussion_r3976714176


##########
docs/health-and-readiness.md:
##########
@@ -54,7 +57,44 @@ endpoint rather than to a check of its own.
 
 The response body carries an overall status and a list of individual checks. 
Each check has a name,
 a status of UP or DOWN, and a details map that explains a failure. On the 
Gravitino server the two
-check names are `httpServer` and `entityStore`.
+normal check names are `httpServer` and `entityStore`. After an observed 
out-of-memory error, all
+three endpoints instead report the `jvm` failure described below.
+
+## Out-of-memory Failures
+
+A Metaspace or heap `OutOfMemoryError` can leave already-loaded endpoints 
responding successfully
+while other operations fail. A successful HTTP response or entity-store lookup 
therefore does not
+prove recovery after OOM.
+
+The Gravitino, Iceberg REST, and Lance REST servers record OOM observed by 
their Jersey exception
+listeners, error mappers, shared request execution/error-response helpers, and 
Jetty worker
+uncaught-exception handlers. The main server also records failures in 
health-probe tasks.
+Wrapped causes are checked too. Once recorded, the affected service’s health 
endpoints and root
+aliases return HTTP 503 with this body (the main server uses the `/api/health` 
prefix):
+
+```json
+{
+  "code": 0,
+  "status": "down",
+  "checks": [
+    {
+      "name": "jvm",
+      "status": "down",
+      "details": { "reason": "OutOfMemoryError; restart required" }
+    }
+  ]
+}
+```
+
+This state lasts until process restart, even if subsequent ordinary API 
requests succeed. Health
+checks skip the entity-store probe once OOM is recorded. A database outage, 
ordinary HTTP 500,
+`StackOverflowError`, or missing connector class alone does not set this state.
+
+Detection covers errors reaching these server boundaries; it cannot detect an 
OOM swallowed
+entirely by a connector or unrelated background executor. This is not a 
JVM-wide OOM trap. If the
+JVM cannot allocate enough memory to answer a probe, the probe may fail 
without a JSON response.
+Each service tracks errors observed within its own runtime. Auxiliary services 
with isolated

Review Comment:
   Doc accuracy: this sentence says the opposite of what the code does. When 
Iceberg REST and Lance REST run embedded in the main server, all three services 
share one `ServerHealth` marker.
   
   - `AuxiliaryServiceManager` builds each auxiliary classloader with 
`IsolatedClassLoader.buildClassLoader`, which passes empty shared and barrier 
lists (`IsolatedClassLoader.java:170-171`).
   - `isSharedClass` returns true for every class where `!isCatalogClass(name)` 
holds (`:273`). `isCatalogClass` only matches `org.apache.gravitino.hive.*` and 
a fixed list of `org.apache.gravitino.catalog.*` prefixes, so 
`org.apache.gravitino.server.web.ServerHealth` is treated as shared.
   - Shared classes are loaded from `baseClassLoader` first (`:238-244`). That 
is the server's context loader, captured at construction (`:71`), and it 
already has `server-common` on its classpath (`server/build.gradle.kts:31`).
   
   The result is a single static `INSTANCE`. An OOM recorded by the main server 
on 8090 makes embedded `/iceberg/health/live` on 9001 return 503, and the 
reverse also happens.
   
   I think sharing is actually the right behaviour: it's one JVM, and an OOM 
anywhere degrades all of it. So the fix belongs in this paragraph, not in the 
code. The PR description has the same inaccuracy ("Auxiliary services with 
isolated classloaders track their own observed errors"). As written, the 
paragraph could lead operators to expect a probe on one port to stay green when 
a co-located service hits OOM.
   



##########
docs/health-and-readiness.md:
##########
@@ -54,7 +57,44 @@ endpoint rather than to a check of its own.
 
 The response body carries an overall status and a list of individual checks. 
Each check has a name,
 a status of UP or DOWN, and a details map that explains a failure. On the 
Gravitino server the two
-check names are `httpServer` and `entityStore`.
+normal check names are `httpServer` and `entityStore`. After an observed 
out-of-memory error, all
+three endpoints instead report the `jvm` failure described below.
+
+## Out-of-memory Failures
+
+A Metaspace or heap `OutOfMemoryError` can leave already-loaded endpoints 
responding successfully
+while other operations fail. A successful HTTP response or entity-store lookup 
therefore does not
+prove recovery after OOM.
+
+The Gravitino, Iceberg REST, and Lance REST servers record OOM observed by 
their Jersey exception
+listeners, error mappers, shared request execution/error-response helpers, and 
Jetty worker
+uncaught-exception handlers. The main server also records failures in 
health-probe tasks.
+Wrapped causes are checked too. Once recorded, the affected service’s health 
endpoints and root
+aliases return HTTP 503 with this body (the main server uses the `/api/health` 
prefix):
+
+```json
+{
+  "code": 0,
+  "status": "down",

Review Comment:
   Doc accuracy: this example body is presented as the response for all three 
services, but the `status` casing differs by server.
   
   `HealthCheckDTO.Status` is a plain enum (`UP`, `DOWN`) with no `@JsonValue`, 
so its JSON casing depends on each server's `ObjectMapper`:
   
   - **Main server:** `ObjectMapperProvider` enables 
`WRITE_ENUMS_TO_LOWERCASE`, so it emits `"down"`. `TestOutOfMemoryHealthHttp` 
asserts exactly this.
   - **Lance REST:** its mapper copies that configuration, so it also emits 
`"down"`.
   - **Iceberg REST:** it registers `IcebergObjectMapperProvider`, and 
`IcebergObjectMapper` only configures field visibility, 
`FAIL_ON_UNKNOWN_PROPERTIES`, kebab-case naming, and `RESTSerializers` 
(`IcebergObjectMapper.java:32-39`). There is no lowercase-enum setting, so it 
emits `"status": "DOWN"`.
   
   Anyone who writes a probe or alert rule that matches `"status": "down"` 
case-sensitively from this example will never see a match on an Iceberg REST 
server that has recorded an OOM.
   
   The PR's own `gravitino-server-config.md` text has the opposite problem: it 
shows `jvm: DOWN` in uppercase for the main server, which actually emits 
lowercase.
   
   Suggestion: show the casing per service, or tell readers to match 
case-insensitively, and make `gravitino-server-config.md` consistent with it.
   



-- 
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