Files
summercms/.planning/phases/11-jobs-realtime-and-search-infrastructure/deferred-items.md
2026-09-30 13:06:46 +02:00

2.2 KiB

Phase 11 deferred items

Out-of-scope findings logged by plan executors. Not fixed; each names the plan that owns the code.

From plan 11-05 (found while debugging beachcomber)

  1. lighthouse broadcast callbacks run after GORM's own commit on single-statement writes (plan 11-03 code). modules/lighthouse/broadcast.go installCallbacks registers lighthouse:after_create, lighthouse:after_update and lighthouse:after_delete with only an After("gorm:after_*") anchor. GORM's callback sorter appends such a callback to the end of the already sorted chain, which is past gorm:commit_or_rollback_transaction. 11-05 observed this directly for the identical beachcomber registration: InstanceGet("gorm:started_transaction") was set, but ConnPool was already the *sql.DB. For a plain gdb.Create outside any explicit transaction, the broadcast job is therefore enqueued after the commit and outside the write's transaction, not "on the write's *sql.Tx" as the lighthouse README states. A failed write still broadcasts nothing, because db.Error is set. Writes inside lagoon.Transaction or a plain gorm transaction are unaffected. Fix: add .Before("gorm:commit_or_rollback_transaction") to the three registrations (beachcomber does this since 9543e65), and add a test for a single-statement write. Candidate owner: plan 11-07 (unit tests).

  2. lagoon hands AfterCommit callbacks a handle that carries the write's statement (plan 11-01 code). modules/lagoon/transaction.go flushStatementAfterCommit builds its handle with db.Session(&gorm.Session{NewDB: true, Context: ctx}), and AfterCommit's immediate path passes the callback's own db. Because a Context is set, Session clones the write's statement (model, table, clauses). A later WithContext on that handle continues from the clone, so a query then runs through the written model's statement. beachcomber defends itself with cleanSession (9543e65). Any other AfterCommit user that calls WithContext or Session without NewDB on the handle it receives would hit the same bug. Fix: pass db.Session(&gorm.Session{NewDB: true, Context: ctx}).Clauses().Session(&gorm.Session{NewDB: true}), or document the requirement. Candidate owner: plan 11-07.