Statistik: Impression-Erfassung asynchron (nicht im Request-Pfad)

Der Seitenaufruf wartete bisher synchron auf den DB-Upsert. Mit
synchronous=FULL (WAL) macht SQLite pro Commit ein fsync -> spuerbare
Latenz pro Seitenaufruf. Die Erfassung laeuft jetzt in einer Goroutine,
die Auslieferung blockiert nicht mehr darauf. Der GeoIP-Lookup war nie
das Problem (mmap, einmal beim Start geoeffnet).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-17 23:57:33 +02:00
parent c4a0c5c378
commit dd714762dc
+10 -2
View File
@@ -92,14 +92,22 @@ func lookupASN(ip net.IP) string {
// und vermerkt das autonome System. Die IP wird zuerst maskiert; sowohl die
// Speicherung als auch die ASN-Auflösung arbeiten nur auf dem anonymisierten
// Netz. Gezielt nur auf den HTML-Seiten-Routen, nicht auf API oder Assets.
//
// Die Erfassung läuft asynchron: der Seitenaufruf darf nicht auf den DB-Schreib
// warten (SQLite serialisiert Schreiber, synchronous=FULL macht pro Commit ein
// fsync). r ist nach Rückkehr des Handlers nicht mehr sicher nutzbar -> wir
// kopieren die zwei Werte vorher heraus.
func trackImpression(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
netw := maskIP(clientIP(r.RemoteAddr))
remote, path := r.RemoteAddr, r.URL.Path
go func() {
netw := maskIP(clientIP(remote))
anon := ""
if netw != nil {
anon = netw.String()
}
recordImpression(r.URL.Path, anon, lookupASN(netw))
recordImpression(path, anon, lookupASN(netw))
}()
next.ServeHTTP(w, r)
})
}