bitflicker64 opened a new pull request, #3139:
URL: https://github.com/apache/hugegraph/pull/3139

   ## Purpose of the PR
   
   - Related to #3137
   
   This is step 2 of the roadmap in #3137. Step 1 (making the creating server 
wait
   for its own `GRAPH_CREATE` event) is a separate, independent change and is 
**not**
   included here: this PR applies to master on its own.
   
   In distributed mode a graph is created on one server while the others 
converge on
   it independently through PD. `CreateGraph` answers before the graph is bound
   everywhere, so a client behind a load balancer can reach a server that still
   answers `Could not rebind [g]`. The window has no upper bound and no 
completion
   signal, which leaves a client no way to know when a new graph is usable.
   
   This adds that signal.
   
   ## Main Changes
   
   **Every server reports the status of a graph it opens.** `LOADING` before the
   backend is opened, `READY` once the graph is bound to the gremlin server,
   `FAILED` when either step fails. Reporting is best effort throughout: every 
write
   is wrapped, so it can never fail or delay a graph creation.
   
   - New `GraphStatus` enum and `GraphStatusEntry`, stored as JSON under
     
`HUGEGRAPH/{cluster}/GRAPHSPACE/{graphspace}/GRAPH_STATUS/{graph}/{server}`.
   - `GraphMetaManager` gains update/get/remove/clear for it, plus a graph-space
     wide clear used when a graph space is dropped.
   - The key is per server, so the report of one server never overwrites 
another's.
     The id is `server.id` when configured, otherwise the host name and the rest
     server port. The rest server url alone is not usable as an identity: the
     shipped image bakes `restserver.url=http://0.0.0.0:8080` into every 
replica.
   - `Events.GRAPH_BOUND` and `Events.GRAPH_BIND_FAILED` are published by
     `ContextGremlinServer.injectGraph` once the three gremlin bindings are 
done, or
     when they throw. `READY` is written from that event only, so it means this
     server can actually serve the graph rather than merely that it opened it. 
The
     graph create event is notified last, after the schema template is applied, 
so
     nothing that can still fail runs after the event that reports the graph 
ready.
   
   **`GET graphspaces/{graphspace}/graphs/{name}/status`** aggregates what the
   servers reported against the servers currently registered for the graph 
space:
   
   ```json
   {
     "graphspace": "DEFAULT",
     "graph": "hugegraph",
     "status": "LOADING",
     "ready_count": 2,
     "total_count": 3,
     "expected_count": 3,
     "servers": [
       {"server": "server-0_8080", "status": "READY", "update_time": 
1754300000000},
       {"server": "server-1_8080", "status": "READY", "update_time": 
1754300000001},
       {"server": "server-2_8080", "status": "LOADING", "update_time": 
1754300000002}
     ]
   }
   ```
   
   It is a readiness gate, so it fails closed:
   
   - `READY` only when every registered server reported `READY`. The servers 
that
     reported are compared by identity, not counted, so the status left behind 
by a
     server that is gone can never stand in for a registered server that never
     reported.
   - When the registered servers can't be listed, `expected_count` is rendered 
as
     `null` and the status stays below `READY` rather than guessing.
   - The status left by a server that is neither registered nor recent is 
dropped,
     so a server that is gone doesn't hold a healthy graph down forever. A 
server
     that is merely slow keeps its status: registrations lapse, and dropping the
     status of a loading server would answer ready too early.
   - `status` is `UNKNOWN` when no server has reported yet, which is distinct 
from a
     graph that doesn't exist (404).
   - A graph config that can't be read is not treated as a graph that was 
dropped.
   
   The failure message published in the status is the exception type only, 
never its
   text: this is served to every member of the graph space while opening a 
graph is
   allowed to the owner only, and backend messages carry data paths and 
connection
   strings. The caller's read permission on the graph is checked explicitly, 
since
   unlike the other reads of this resource this one has to answer for a graph 
that
   is not open yet and so can't rely on opening it to verify.
   
   ## Verifying these changes
   
   - [x] Need tests and can be verified as follows:
       - 55 new unit tests in `hugegraph-test`, registered in `UnitTestSuite`:
         `GraphStatusAggregateTest`, `GraphStatusEntryTest`,
         `GraphMetaManagerStatusTest`, `GraphManagerStatusTest`,
         `GraphStatusAPITest`. They cover the aggregation rules and their
         boundaries, the metadata key layout, the reported state machine driven
         through a real event hub, and the endpoint including the 403 and 404 
paths.
       - Full unit suite locally: 647 run, with only the pre-existing
         `SecurityManagerTest` (11) and `CollectionFactoryTest` (3) failures, 
which
         reproduce identically on a clean checkout of master under the same JDK.
   
   ## Does this PR potentially affect the following parts?
   
   - [x]  The public API
   
   Additive only: one new read-only endpoint. No existing response shape 
changes.
   `server.id` is now read in production; its description should be updated, as 
it
   is still documented as a legacy option.
   
   ## Documentation Status
   
   - [x]  `Doc - TODO`
   
   The endpoint carries its swagger annotations, from which the served OpenAPI
   document is generated. Prose documentation belongs in a follow up on
   apache/hugegraph-doc.
   
   ## Known limitations
   
   Raising these here rather than leaving them to be found:
   
   - Nothing reaps the status of a server that never comes back, and there is no
     TTL; entries are filtered when read, not deleted. A deployment that mints 
a new
     host name per reschedule accumulates one entry per graph per generation.
   - Two concurrent lazy opens of the same graph on one server can leave a 
`FAILED`
     behind, since the loser of the race fails on the unique-option check.
   - A server that restarts is trusted while it reopens its graphs, because it
     registers with PD before it starts opening them.
   - Nothing enforces that `server.id` is unique when it is set explicitly.
   - The staleness window is a constant rather than an option.
   
   Happy to take direction on which of these to fold in here and which belong in
   step 3, where PD owns the creation and most of them go away by construction.
   


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


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to