feat(go-services): Phase 2 foundation — isolated shadow DB + schema
Stands up the shadow-ingest substrate without touching production: - schema.go: faithful replica of db_async.init_db_async (idempotent DDL), run only when an instance OWNS its DB (READ_ONLY=false). Fixes for a fresh DB: spawn_events has no sole-id PK (so it can be a hypertable), telemetry_events compression is enabled before its policy, and the portal unique index uses ROUND(..,1) to match main.py's ON CONFLICT. 35/35 statements OK. - store.go: read-only transaction enforcement is now conditional (on for production read parity, off for ingest). - main.go: READ_ONLY + SHADOW_INGEST_WS config; schema init on boot when owning the DB. - compose override: a SEPARATE TimescaleDB `dereth-go-db` (isolated volume, 127.0.0.1:5434) and a `dereth-tracker-go-shadow` instance (image reused via dereth-tracker-go:local) that owns it. Production DB never written. Verified: dereth_go has all 13 tables; telemetry_events + spawn_events are hypertables; the read-side instance still serves production read-only. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
b6d2871cf0
commit
6a839e69bc
4 changed files with 277 additions and 12 deletions
|
|
@ -22,6 +22,7 @@ services:
|
|||
context: ./go-services/tracker-go
|
||||
args:
|
||||
BUILD_VERSION: ${BUILD_VERSION:-dev}
|
||||
image: dereth-tracker-go:local
|
||||
container_name: dereth-tracker-go
|
||||
ports:
|
||||
- "127.0.0.1:8770:8770"
|
||||
|
|
@ -72,3 +73,53 @@ services:
|
|||
options:
|
||||
max-size: "10m"
|
||||
max-file: "3"
|
||||
|
||||
# ---- Phase 2: shadow ingest (fully isolated; production never touched) ----
|
||||
|
||||
# A SEPARATE TimescaleDB the Go tracker owns for shadow ingest. Isolated
|
||||
# volume + loopback port; the production dereth DB is never written.
|
||||
dereth-go-db:
|
||||
image: timescale/timescaledb:2.19.3-pg14
|
||||
container_name: dereth-go-db
|
||||
ports:
|
||||
- "127.0.0.1:5434:5432"
|
||||
environment:
|
||||
POSTGRES_DB: "dereth_go"
|
||||
POSTGRES_USER: "postgres"
|
||||
POSTGRES_PASSWORD: "${POSTGRES_PASSWORD}"
|
||||
volumes:
|
||||
- dereth-go-data:/var/lib/postgresql/data
|
||||
restart: unless-stopped
|
||||
logging:
|
||||
driver: "json-file"
|
||||
options:
|
||||
max-size: "10m"
|
||||
max-file: "3"
|
||||
|
||||
# Shadow tracker instance: same image, but OWNS dereth-go-db (read-write) and
|
||||
# (once ingest lands) consumes the Python /ws/live firehose into it, so its
|
||||
# ingest output can be compared against production without writing to it.
|
||||
dereth-tracker-go-shadow:
|
||||
image: dereth-tracker-go:local
|
||||
container_name: dereth-tracker-go-shadow
|
||||
ports:
|
||||
- "127.0.0.1:8771:8771"
|
||||
environment:
|
||||
PORT: "8771"
|
||||
DATABASE_URL: "postgresql://postgres:${POSTGRES_PASSWORD}@dereth-go-db:5432/dereth_go"
|
||||
READ_ONLY: "false" # owns its DB; creates schema on boot
|
||||
INVENTORY_SERVICE_URL: "http://inventory-service:8000"
|
||||
SECRET_KEY: "${SECRET_KEY}"
|
||||
# SHADOW_INGEST_WS: "ws://dereth-tracker:8765/ws/live" # enabled once ingest handlers land
|
||||
LOG_LEVEL: "INFO"
|
||||
depends_on:
|
||||
- dereth-go-db
|
||||
restart: unless-stopped
|
||||
logging:
|
||||
driver: "json-file"
|
||||
options:
|
||||
max-size: "10m"
|
||||
max-file: "3"
|
||||
|
||||
volumes:
|
||||
dereth-go-data:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue