feat: QQQ attribution and N+1 detection (QQQ 4.1.0-RC.13); cuts 0.1.0-RC.1 #7

Merged
KofTwentyTwo merged 3 commits from feature/attribution into develop 2026-10-15 17:55:23 +00:00
KofTwentyTwo commented 2026-10-15 17:50:44 +00:00 (Migrated from github.com)

Phase B2 of docs/SPEC.md section 5, on QQQ 4.1.0-RC.13 (qqq#1226, statement execution listener SPI).

  • AttributionListener (core StatementExecutionListener): aggregates statements per unit of work (HTTP route template, scheduled job, process), process, table, operation and statement fingerprint in bounded memory (attribution_max_keys, overflow into (other)), with per-unit sampling. Ignores the qbit's own db_perf_ tables and the flusher thread, so it never measures itself.
  • N+1: per unit of work, statement shapes repeated at least n_plus_one_threshold times become db_perf_repeat_pattern rows (units affected, max and total repeats).
  • AttributionFlusher: per-pod daemon; every attribution_flush_seconds swaps the aggregates and writes one batched insert per table as the system user; never retries forever or blocks statement threads; flushes once on shutdown. Registered as a QQQ runtime service; hosts without the launcher call DbPerfRuntime.of(instance).startAttribution().
  • Pom: QQQ 4.1.0-RC.13.

Tests: 102 (H2 + PostgreSQL 17) against released RC.13, checkstyle clean, JaCoCo gate met. Implementation by Codex, reviewed by Claude.

Labelled release:rc: merging cuts qbit-db-performance 0.1.0-RC.1.

🤖 Generated with Claude Code

Phase B2 of docs/SPEC.md section 5, on QQQ 4.1.0-RC.13 (qqq#1226, statement execution listener SPI). - `AttributionListener` (core `StatementExecutionListener`): aggregates statements per unit of work (HTTP route template, scheduled job, process), process, table, operation and statement fingerprint in bounded memory (`attribution_max_keys`, overflow into `(other)`), with per-unit sampling. Ignores the qbit's own `db_perf_` tables and the flusher thread, so it never measures itself. - N+1: per unit of work, statement shapes repeated at least `n_plus_one_threshold` times become `db_perf_repeat_pattern` rows (units affected, max and total repeats). - `AttributionFlusher`: per-pod daemon; every `attribution_flush_seconds` swaps the aggregates and writes one batched insert per table as the system user; never retries forever or blocks statement threads; flushes once on shutdown. Registered as a QQQ runtime service; hosts without the launcher call `DbPerfRuntime.of(instance).startAttribution()`. - Pom: QQQ 4.1.0-RC.13. Tests: 102 (H2 + PostgreSQL 17) against released RC.13, checkstyle clean, JaCoCo gate met. Implementation by Codex, reviewed by Claude. Labelled `release:rc`: merging cuts qbit-db-performance 0.1.0-RC.1. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Sign in to join this conversation.