Persist and expose multi-battle station state#353
Persist and expose multi-battle station state#353Mygod wants to merge 11 commits intoUnownHash:mainfrom
Conversation
|
I'll leave others to comment on whether this is desirable functionality. I don't really care much one way or the other. I do have a few comments on the way its implemented as this doesn't follow commonly held patterns within the code base, or even guidelines in claude.md An automated review highlights some quite significant variances and performance observations - I haven't bothered with a human review until others chime in about whether the capability is one we want to have or not. Database Write Impact — Significant Change Before: Station updates go through the write-behind queue (batched, coalesced, deferred). After: Every station GMO update now also does a synchronous transactional write outside the write-behind queue: BEGIN That's 4 DB round-trips per station per GMO, executed synchronously while holding the station lock. This blocks other goroutines waiting The write goes to GeneralDb (shared connection pool), so it competes with all other non-pokemon writes. Performance Concerns
Pattern Adherence Follows patterns well:
Deviates from patterns:
|
|
Looking at the CLAUDE.md instructions, let me check which PR patterns violate the documented rules. Code Review — Pattern Compliance with Project ArchitectureThe project's 1. Write-behind queue for persistence
Every other persisted entity (pokemon, gym, pokestop, station, spawnpoint) uses the write-behind queue for DB persistence. This has practical consequences: 4 DB round-trips per station per GMO, no coalescing of repeated updates, and the station lock is held 2. Entity struct pattern
3. Record access pattern
Station battles have no record access functions. The 4. Setter methods with dirty tracking
|
|
ReactMap PR is done. From my testing, everything seems ok. Feel free to complain now. :) I'm also planning to do another review pass in two days. |
Why
Max Battles can temporarily override a station's normal local battle. Golbat previously stored only one flat
battle_*payload onstation, so a temporary event battle would overwrite the local one and the original state would be lost for planning and downstream filtering.This PR adds first-class multi-battle support for stations while keeping the existing flat station/webhook fields for compatibility.
Ground rule
Latest observed game data is treated as ground truth.
For a given station:
battle_endthan another known battle on the same station, the older/equal-ending row is treated as obsolete and removedThis keeps temporary overrides and later event rotations aligned with the most recent game state instead of waiting for old rows to expire naturally.
What this PR adds
station_battletable via migration54_station_battle.up.sqlstationrowstation.battle_*battlesarray in station API andmax_battlewebhook payloadsstation_battlerows in both preload and lazy station readsstation_battlecleanup supportCanonical battle behavior
A station can now know about multiple non-expired battles, but one battle is still chosen as the canonical representative for:
station.battle_*max_battlewebhook fieldsSelection rule:
battle_endwins among surviving rowsThe full
battlesarray remains available for planning use cases.Identity / persistence
bread_battle_seedis used as the persisted battle identity.Live validation before implementation showed:
That made seed the best available battle-instance identifier for persistence.
API / webhook impact
Backward compatibility is preserved:
battle_*station fields remainmax_battlewebhook fields remainNew additive fields:
battlesmax_battlewebhook:battlesThis allows downstream consumers to keep working unchanged while giving planning-oriented consumers the full set.
Deployment notes
54_station_battle.up.sqlis included and runs automatically on startupstation.battle_*intostation_battleis includedstation_battledepends on normal rescans after deploycleanup.station_battlesPractical rollout expectation:
Validation
Tested with:
go test ./decoder -run 'StationBattle|StationWebhooks|BuildStationResult|FortLookup|SyncStation|Preload'go test ./... -run '^$'Post-deploy live DB checks on one environment showed:
54stationandstation_battlestation_battlerows missing boss dataNotes
This PR is intended to preserve battles for planning, especially around Monday / Max Battle event overlaps, while keeping existing API and webhook consumers stable.
Fixes #352.