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]