feat(go-services): tracker share_* handlers (complete ingest) + shadow tuning
- share.go: cross-machine vital sharing (share_subscribe/unsubscribe/share_*), faithful port of the peer-state snapshot + plugin fan-out + /vital-sharing/peers. The last ingest handler — the Go tracker now handles every plugin event type. - shadow consumer: drop the outbound keepalive ping (the firehose is never idle) and tighten the read-deadline watchdog to 12s for faster reconnect after the upstream's periodic eviction (full-firehose browser clients get evicted ~every 90s; the watchdog recovers it, ~90% duty cycle). Production-bound /ws/position is unaffected (plugins connect to us; no eviction). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
27757636e4
commit
5b2db439a3
6 changed files with 171 additions and 27 deletions
|
|
@ -32,16 +32,21 @@ type Ingestor struct {
|
|||
liveCombatStats map[string]map[string]any
|
||||
dungeonMapCache map[string]map[string]any
|
||||
questStatus map[string]map[string]string
|
||||
lastKills map[string]int // "session_id|character_name" -> kills
|
||||
lastKills map[string]int // "session_id|character_name" -> kills
|
||||
combatLastSession map[string]map[string]any // "char:session_id" -> last cumulative session
|
||||
combatLifetimeCache map[string]map[string]any // character_name -> accumulated lifetime
|
||||
vitalSubscribers map[string]bool
|
||||
vitalPeerState map[string]map[string]any
|
||||
|
||||
plugins *pluginRegistry // for share_* fan-out + plugin_connected status
|
||||
}
|
||||
|
||||
func newIngestor(pool *pgxpool.Pool, log *slog.Logger, broadcast func(map[string]any)) *Ingestor {
|
||||
func newIngestor(pool *pgxpool.Pool, log *slog.Logger, broadcast func(map[string]any), plugins *pluginRegistry) *Ingestor {
|
||||
return &Ingestor{
|
||||
pool: pool,
|
||||
log: log,
|
||||
broadcast: broadcast,
|
||||
plugins: plugins,
|
||||
liveSnapshots: map[string]map[string]any{},
|
||||
liveVitals: map[string]map[string]any{},
|
||||
liveCharacterStats: map[string]map[string]any{},
|
||||
|
|
@ -53,6 +58,8 @@ func newIngestor(pool *pgxpool.Pool, log *slog.Logger, broadcast func(map[string
|
|||
lastKills: map[string]int{},
|
||||
combatLastSession: map[string]map[string]any{},
|
||||
combatLifetimeCache: map[string]map[string]any{},
|
||||
vitalSubscribers: map[string]bool{},
|
||||
vitalPeerState: map[string]map[string]any{},
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -84,10 +91,17 @@ func (i *Ingestor) dispatch(ctx context.Context, data map[string]any) {
|
|||
i.handleDungeonMap(data)
|
||||
case t == "combat_stats":
|
||||
i.handleCombatStats(ctx, data)
|
||||
case t == "share_subscribe":
|
||||
i.handleShareSubscribe(data)
|
||||
case t == "share_unsubscribe":
|
||||
i.handleShareUnsubscribe(data)
|
||||
return // unsubscribe broadcasts its own share_peer_removed; don't re-broadcast
|
||||
case strings.HasPrefix(t, "share_"):
|
||||
i.handleShareUpdate(t, data)
|
||||
case t == "register":
|
||||
// no DB / no broadcast; plugin_conns belongs to the /ws/position server
|
||||
case strings.HasPrefix(t, "share_"), t == "chat":
|
||||
// share_* handled in a later pass; chat is broadcast-only
|
||||
case t == "chat":
|
||||
// broadcast-only
|
||||
}
|
||||
if i.broadcast != nil {
|
||||
i.broadcast(data)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue