Why
Closes #126. The activity feed — a repository’s Activity tab, the instance-wide
one, and the home page’s per-repository feed — found closed, reopened and merged
events by reading the last 200 metadata commit subjects on every render. That is
one git log process per repository per request, so the instance home with N
repositories ran N of them. It was the last derived read still going to git.
What changed
- A
state_changestable fed by the same refresh: a delta reads the commits in its range, a rebuild reads the whole metadata branch. Rows are keyed by the commit, so a retried or overlapping refresh cannot duplicate an event; an ordinal keeps two changes in the same second in branch order (commit times are seconds, and a close followed by a reopen often shares one). Store.StateChangesreturns the events newest first. The feed reads it and keeps the metadata log as the fallback for a server without an index or a failed read.git.Repo.LogandCommitsBetweentreat a limit of zero as no limit (the rebuild needs all of history), andmetadata.ParseStateSubjectis exported so the index derives the events without a second copy of the format.- The load harness gains
activity,instance-activityandhomescenarios, anddocs/load-testing.mdlists them.
What it saves
The activity page starts no metadata log; the instance home and the instance activity page lose one process per visible repository. With three repositories on the harness at concurrency 4:
| page | req/s | p50 | p90 | p99 |
|---|---|---|---|---|
| activity | 496.4 | 7 ms | 11 ms | 16 ms |
| instance activity | 230.4 | 17 ms | 20 ms | 27 ms |
| home | 202.2 | 20 ms | 22 ms | 26 ms |
Tests
forge/index/activity_test.go: close and reopen produce two events newest first
with actor and time; repeated refreshes do not duplicate; IndexRepo and the
incremental path produce identical events for an issue and a request close.
Existing activity integration tests now exercise the index path unchanged.
Checks
gofmt, go vet ./..., python3 scripts/check-links.py, ./vole workflow check, and the full -race suite with GOFLAGS=-tags=sqlite_fts5.
Notes
The latest commit and the tag list still come from git: they are content, not a derived row. Schema version 7 rebuilds each repository on its first read after upgrade.