fix(outbound): record-change listener only costs queries for configured source tables #23

Merged
KofTwentyTwo merged 1 commits from fix/outbound-enqueue-table-cache into develop 2026-10-15 12:38:22 +00:00
KofTwentyTwo commented 2026-10-15 12:26:09 +00:00 (Migrated from github.com)

Production hotfix (kof22): OutboundEnqueue is a global RecordChangeListener. appliesTo accepted every non-edi_ table, and onRecordsChanged opened a system session and queried edi_agreement_document per record. Every insert/update to audit, auditDetail, worm_audit_chain, jobs, alerts, etc. paid for that, and UPDATEs also fetched old records because the listener applied.

Change

  • New OutboundSourceTables (one per EdiRuntime) caches the source tables that have an active RECORD_CHANGE OUTBOUND document on an active agreement. It is loaded once, from committed data only. appliesTo reads from the cache, so writes to any other table do no work (no session, no query, no old-record fetch).
  • Invalidation: appliesTo accepts edi_agreement and edi_agreement_document (all change types). A change bumps the cache generation right away and again after the transaction commits, so a reload that raced the uncommitted change is thrown away. Until the commit, the changing transaction bypasses the cache and sees its own definitions. A 60s TTL covers definition changes made by another pod or process.
  • onRecordsChanged resolves definitions (documents plus active agreements) once per event instead of once per record.
  • MANUAL (matches every trigger) and ESB_EVENT (event-id dedupe) work as before. If the EDI runtime isn't installed, appliesTo returns false.

Tests (OutboundSourceTablesTest)

  • Unconfigured table: appliesTo returns false for INSERT and UPDATE. Five inserts cause no cache reload and enqueue nothing.
  • Configured table still enqueues once per record, and a second event doesn't reload the cache.
  • Deactivating and reactivating the document or the agreement invalidates the cache, and the inactive state enqueues nothing.
  • A transaction that adds a document and then writes the source enqueues before it commits. A rolled-back definition leaves the cache unchanged.

./mvnw verify (checkstyle, all tests, JaCoCo gates) passes locally. Merging with release:rc cuts the next RC.

🤖 Generated with Claude Code

Production hotfix (kof22): `OutboundEnqueue` is a global RecordChangeListener. `appliesTo` accepted every non-`edi_` table, and `onRecordsChanged` opened a system session and queried `edi_agreement_document` per record. Every insert/update to audit, auditDetail, worm_audit_chain, jobs, alerts, etc. paid for that, and UPDATEs also fetched old records because the listener applied. **Change** - New `OutboundSourceTables` (one per `EdiRuntime`) caches the source tables that have an active `RECORD_CHANGE` OUTBOUND document on an active agreement. It is loaded once, from committed data only. `appliesTo` reads from the cache, so writes to any other table do no work (no session, no query, no old-record fetch). - Invalidation: `appliesTo` accepts `edi_agreement` and `edi_agreement_document` (all change types). A change bumps the cache generation right away and again after the transaction commits, so a reload that raced the uncommitted change is thrown away. Until the commit, the changing transaction bypasses the cache and sees its own definitions. A 60s TTL covers definition changes made by another pod or process. - `onRecordsChanged` resolves definitions (documents plus active agreements) once per event instead of once per record. - MANUAL (matches every trigger) and ESB_EVENT (event-id dedupe) work as before. If the EDI runtime isn't installed, `appliesTo` returns false. **Tests** (`OutboundSourceTablesTest`) - Unconfigured table: `appliesTo` returns false for INSERT and UPDATE. Five inserts cause no cache reload and enqueue nothing. - Configured table still enqueues once per record, and a second event doesn't reload the cache. - Deactivating and reactivating the document or the agreement invalidates the cache, and the inactive state enqueues nothing. - A transaction that adds a document and then writes the source enqueues before it commits. A rolled-back definition leaves the cache unchanged. `./mvnw verify` (checkstyle, all tests, JaCoCo gates) passes locally. Merging with `release:rc` cuts the next RC. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Sign in to join this conversation.