feat: backend service

This commit is contained in:
Ilia Denisov
2026-05-06 10:14:55 +03:00
committed by GitHub
parent 3e2622757e
commit f446c6a2ac
1486 changed files with 49720 additions and 266401 deletions
+39 -34
View File
@@ -7,28 +7,30 @@ readiness, shutdown, and push or revoke incidents.
Before starting the process, confirm:
- `GATEWAY_REDIS_MASTER_ADDR` and `GATEWAY_REDIS_PASSWORD` point to the Redis
deployment used for session lookup, replay reservations, session-events
consumption, and client-events fan-out. Optional read replicas may be
listed in `GATEWAY_REDIS_REPLICA_ADDRS` (currently unused; reserved for
future read-routing).
- `GATEWAY_SESSION_EVENTS_REDIS_STREAM` and
`GATEWAY_CLIENT_EVENTS_REDIS_STREAM` reference existing Redis Stream keys
or the names publishers will use.
- `GATEWAY_RESPONSE_SIGNER_PRIVATE_KEY_PEM_PATH` points to a readable PKCS#8
PEM-encoded Ed25519 private key.
- `GATEWAY_REDIS_MASTER_ADDR` and `GATEWAY_REDIS_PASSWORD` point to the
Redis deployment used for anti-replay reservations. Optional read
replicas may be listed in `GATEWAY_REDIS_REPLICA_ADDRS` (currently
unused; reserved for future read-routing).
- `GATEWAY_BACKEND_HTTP_URL`, `GATEWAY_BACKEND_GRPC_PUSH_URL`, and
`GATEWAY_BACKEND_GATEWAY_CLIENT_ID` describe the consolidated backend
service the gateway forwards every public auth and authenticated
user/lobby request to and the gRPC push subscription it opens.
- `GATEWAY_RESPONSE_SIGNER_PRIVATE_KEY_PEM_PATH` points to a readable
PKCS#8 PEM-encoded Ed25519 private key.
- the configured Redis DB and key-prefix settings match the target
environment. Per `ARCHITECTURE.md §Persistence Backends`, Redis traffic is
password-protected and TLS is disabled by policy; the deprecated
`GATEWAY_REDIS_TLS_ENABLED` and `GATEWAY_REDIS_USERNAME` variables are no
longer accepted and cause a hard fail at startup.
environment. Per `ARCHITECTURE.md §Persistence Backends`, Redis traffic
is password-protected and TLS is disabled by policy; the deprecated
`GATEWAY_REDIS_TLS_ENABLED` and `GATEWAY_REDIS_USERNAME` variables are
no longer accepted and cause a hard fail at startup.
At startup the process opens one shared `*redis.Client` (instrumented via
OpenTelemetry tracing and metrics) and performs one bounded `PING`. The
session cache, replay store, session-events subscriber, and client-events
subscriber all use that client.
At startup the process opens one shared `*redis.Client` (instrumented
via OpenTelemetry tracing and metrics) and performs one bounded `PING`
for the replay store. It also dials backend's gRPC push listener and
opens one `Push.SubscribePush` stream that reconnects with capped
exponential backoff on failure.
Startup fails fast if the ping fails or if the signer key cannot be loaded.
Startup fails fast if the Redis ping fails, the backend URL is
malformed, or the signer key cannot be loaded.
Expected listener state after a healthy start:
@@ -96,13 +98,15 @@ During planned restarts:
If a revoked session still sends traffic or keeps an active stream:
1. verify that the auth/session side published a session snapshot with the
same `device_session_id` and `status=revoked`;
2. verify that the event was written to
`GATEWAY_SESSION_EVENTS_REDIS_STREAM`;
3. verify the gateway is connected to the same Redis address, DB, and stream;
4. confirm the snapshot fields are complete and well-formed;
5. check that a later active snapshot did not overwrite the revoked one.
1. verify that backend recorded the revocation (the
`/api/v1/internal/sessions/{id}` lookup must return `status=revoked`
for that device session);
2. verify that backend emitted the corresponding `session_invalidation`
frame on `Push.SubscribePush` and that the gateway logs a
matching subscription closure;
3. verify the gateway is connected to the same backend instance via
`GATEWAY_BACKEND_HTTP_URL` / `GATEWAY_BACKEND_GRPC_PUSH_URL`;
4. confirm the next authenticated request from that session is rejected.
Expected gateway behavior after the revoke snapshot is consumed:
@@ -116,16 +120,17 @@ Expected gateway behavior after the revoke snapshot is consumed:
If a client reports missing push events:
1. confirm that the client successfully opened `SubscribeEvents`;
2. confirm the stream received the initial `gateway.server_time` bootstrap
event;
3. confirm the gateway consumed the expected entry from
`GATEWAY_CLIENT_EVENTS_REDIS_STREAM`;
4. verify `user_id` and optional `device_session_id` in the stream entry match
the intended target;
2. confirm the stream received the initial `gateway.server_time`
bootstrap event;
3. confirm the gateway consumed the expected `pushv1.PushEvent` from
backend (look for `push_dispatcher` log lines or
`grpc_push_events_total` increments on the backend side);
4. verify `user_id` and optional `device_session_id` on the
`ClientEvent` match the intended target;
5. confirm the event payload fields are well-formed and not dropped as
malformed;
6. check whether the stream was closed earlier because of revoke, shutdown, or
overflow.
6. check whether the stream was closed earlier because of revoke,
shutdown, or overflow.
### Stream Closed Unexpectedly