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
+21 -41
View File
@@ -1,43 +1,33 @@
# Decision: Redis configuration shape
PG_PLAN.md §7. Captures the standing rules adopted by Edge Gateway when it
joined the project-wide Redis topology defined in
`ARCHITECTURE.md §Persistence Backends`.
Captures the standing rules adopted by Edge Gateway when it joined the
project-wide Redis topology described in `ARCHITECTURE.md`.
## Context
Gateway intentionally stays Redis-only. All gateway state Redis serves is
TTL-bounded or runtime-coordination state:
Gateway intentionally stays Redis-light. The only Redis state served by
gateway is the replay reservation namespace (short-lived `SETNX` per
authenticated request, bounded by
`GATEWAY_REPLAY_REDIS_RESERVE_TIMEOUT`). Session lookup goes through
backend's REST surface, and inbound events are delivered through the
gRPC `Push.SubscribePush` consumer (see
`gateway/internal/backendclient`).
- the session cache is a read-through projection of authsession's
source-of-truth session records (rebuildable via re-authentication);
- the replay store is a short-lived `SETNX` reservation namespace per
authenticated request (`GATEWAY_REPLAY_REDIS_RESERVE_TIMEOUT`);
- the session-events stream is a runtime fan-out of session lifecycle
updates;
- the client-events stream is a runtime push fan-out.
Stage 7 brought gateway in line with the steady-state rules established in
Stage 0: every Galaxy service uses one master plus zero-or-more replicas
with a mandatory password, no TLS, and no Redis ACL username; the connection
is configured by the shared `pkg/redisconn` helper.
The shared rule is: every Galaxy service uses one master plus
zero-or-more replicas with a mandatory password, no TLS, and no Redis
ACL username; the connection is configured by the shared
`pkg/redisconn` helper.
## Decisions
### One shared `*redis.Client` owned by the runtime
`cmd/gateway/main.go` constructs a single `*redis.Client` via
`internal/redisclient.NewClient`, attaches OpenTelemetry tracing and metrics
via `internal/redisclient.InstrumentClient`, performs one bounded `PING`
via `internal/redisclient.Ping`, and registers `client.Close` for shutdown.
The session cache, replay store, session-events subscriber, and
client-events subscriber all receive this same client.
Adapters no longer build or own a Redis client. Their `Config` structs hold
only behavior settings (key prefix, stream name, per-subsystem timeouts).
Adapter constructors take `(*redis.Client, …)`. The stream subscribers'
`Close`/`Shutdown` methods became no-ops; the runtime's context cancellation
unblocks the `XRead` loop and the runtime closes the shared client.
`internal/redisclient.NewClient`, attaches OpenTelemetry tracing and
metrics via `internal/redisclient.InstrumentClient`, performs one
bounded `PING` via `internal/redisclient.Ping`, and registers
`client.Close` for shutdown. The replay store is the only adapter
backed by Redis.
### One env-var prefix for the connection
@@ -51,17 +41,10 @@ Connection topology is loaded from a single `GATEWAY_REDIS_*` group via
- `GATEWAY_REDIS_DB` (default `0`)
- `GATEWAY_REDIS_OPERATION_TIMEOUT` (default `250ms`)
Per-subsystem behavior env vars keep their existing prefixes — they do not
describe connection topology, only namespace and timing:
Per-subsystem behavior env vars (namespace and timing only):
- `GATEWAY_SESSION_CACHE_REDIS_KEY_PREFIX`,
`GATEWAY_SESSION_CACHE_REDIS_LOOKUP_TIMEOUT`
- `GATEWAY_REPLAY_REDIS_KEY_PREFIX`,
`GATEWAY_REPLAY_REDIS_RESERVE_TIMEOUT`
- `GATEWAY_SESSION_EVENTS_REDIS_STREAM`,
`GATEWAY_SESSION_EVENTS_REDIS_READ_BLOCK_TIMEOUT`
- `GATEWAY_CLIENT_EVENTS_REDIS_STREAM`,
`GATEWAY_CLIENT_EVENTS_REDIS_READ_BLOCK_TIMEOUT`
### Retired env vars (hard removal)
@@ -96,11 +79,8 @@ downstream dashboards will start populating without further changes.
## Consequences
- Gateway test code that previously constructed a Redis client per adapter
must now construct one client and pass it to every adapter under test
(see `internal/session/redis_test.go`, `internal/replay/redis_test.go`,
`internal/events/subscriber_test.go`,
`internal/events/client_subscriber_test.go`).
- Gateway test code constructs one shared client and passes it to the
replay-store adapter under test (see `internal/replay/redis_test.go`).
- Operators must set `GATEWAY_REDIS_PASSWORD`. A passwordless local Redis
is still acceptable as long as a placeholder password is supplied to the
binary; Redis without `requirepass` accepts AUTH unconditionally.