Pinned event-mongodb monitor acquisition signals and completion caller boundaries
Parent: Change Data Capture Patterns · Published reference · snapshot 2026-11-02
↓ Facts as markdownall context files
Source-anchored research for Pinned event-mongodb monitor acquisition signals and completion caller boundaries. Run status: COMPLETED.
These notes link each claim to its source. Some citations identify archived research reports that are no longer hosted on this site. A published reference means the content is available; it does not certify independent review or accuracy.Read the editorial policy and follow the sources before relying on a claim.
How it works
- `AcquisitionPending` is the first `iota` value, and a fresh `AcquisitionSignal` reads its atomic integer through `Result()`. Neither monitor caller requires `AcquisitionAcquired` before completing: an untouched pending signal falls through to status classification and a completion attempt. This is a caller-control-flow inference, not proof of acquisition. (medium confidence) [source 1] [source 2] [source 3]
- The MongoStore adapters make the two caller paths converge: RecordStart creates a pending entry and delegates to Record, while RecordComplete delegates to UpdateStatus with the supplied event and subscription IDs. Thus, when these callers monitor WorkerPool deliveries against this MongoStore, their completion attempts address the same normalized event/subscription key used at start. (medium confidence) [source 1] [source 2] [source 3]
Problems, failure modes and limitations
- Both callers attempt their start write before injecting a fresh `AcquisitionSignal` and invoking the next handler. They inject the signal only in WorkerPool mode. On return, they suppress completion only when the signal result is `AcquisitionSkipped`; they return the original handler error from that branch. (medium confidence) [source 1] [source 2]
- If `WorkerPoolMiddleware` has no message ID, it invokes `next` before setting any signal. An acquisition error sets `AcquisitionAcquired` and invokes `next` as a fail-open path; an unsuccessful acquisition sets `AcquisitionSkipped` and returns nil; successful acquisition also sets `AcquisitionAcquired`. Consequently an acquired signal alone does not establish that `Acquire` succeeded, and the monitor skip condition does not enforce ownership. (medium confidence) [source 1] [source 2] [source 3] [source 4]
- Both monitor callers default the final status to completed for a nil downstream error. For a non-nil error they call `ClassifyError`: `ResultNack` and `ResultDefer` map to retrying, `ResultReject` to failed, `ResultAck` to completed, and the default branch to retrying. They measure the duration around `next`, so an outer monitor measures the wrapped middleware call as well as any handler work it performs. (medium confidence) [source 1] [source 2]
- The debugging guide's first-recorder attribution warning agrees with the traced caller paths: `NewMiddleware` writes its configured instance identifier before invoking the worker middleware. A WorkerPool start uses `$setOnInsert`, whereas `UpdateStatus` sets status, duration and completion time, with an error field only for a non-nil error. Completion does not replace `instance_id` or trace fields. The signal controls completion suppression but does not transfer a winner identity into the stored entry; the retained start identity cannot by itself identify the worker that acquired or completed the message. (medium confidence) [source 1] [source 2] [source 3] [source 4] [source 5]
- In the acquired worker path, `WorkerPoolMiddleware` invokes the downstream handler and then attempts `coord.MarkProcessed` on nil error; a marking error is logged and the downstream error is still returned. When a monitor wraps this call, its completed status follows that returned error classification. Completed monitoring alone therefore does not prove the coordinator marking succeeded or establish an atomic combined business-effect/checkpoint protocol. (medium confidence) [source 1] [source 2] [source 3]
Comparisons and alternatives
- The GoDoc call `monitor.NewMiddleware` corresponds to the `NewMiddleware` declaration with a `Store` parameter; the GoDoc call `event.MonitorMiddleware` corresponds to `MonitorMiddleware` with a `MonitorStore` parameter. Their callbacks make start and completion writes best effort: they warn only if a context logger exists, continue to `next` after a start error, and return `handlerErr` rather than a monitor-store error. The first declaration calls `store.Record` and `store.UpdateStatus`; the second calls `store.RecordStart` and `store.RecordComplete`. (medium confidence) [source 1] [source 2]
- The two monitor callers provide best-effort lifecycle observations rather than a success condition for persistence: they continue after start-write errors and return the downstream result even if completion writing fails. MongoStore `UpdateStatus` discards the update result and returns nil when the driver reports no error; this method does not check a matched-document count. A returned handler result therefore does not establish that a corresponding monitor entry was persisted or updated. (medium confidence) [source 1] [source 2] [source 3]
Facts and statements
- Both monitor callers replace the context subscription ID with an empty string in WorkerPool mode and use that normalized ID for both start and completion calls. They preserve the context worker group on the start record, but neither completion call passes a worker group. (medium confidence) [source 1] [source 2]
- The monitor GoDoc example calls `monitor.NewMiddleware` with `monitor.WithMiddlewareMode(monitor.WorkerPool)`. The `NewMiddleware` declaration applies supplied options to `o` before constructing its callback; `detectDeliveryMode` returns a non-nil explicit mode, otherwise detects WorkerPool from context and falls back to Broadcast. The core GoDoc example calls `event.MonitorMiddleware`; that declaration directly tests `ContextDeliveryMode(ctx) == WorkerPool`. Each caller injects its signal only for its effective WorkerPool mode, so an inner worker middleware alone does not enable injection. (medium confidence) [source 1] [source 2]
- Attributed identity conflict: the debugging guide describes WorkerPool matching by `worker_group` and one entry per event per worker group. The pinned MongoStore record/status predicates and unique index use only `event_id` plus `subscription_id`, while both monitor callers supply an empty subscription ID in WorkerPool mode. For those callers using the same collection and event ID, group metadata does not partition this monitor key. (low confidence) [source 1] [source 2] [source 3] [source 4]
- The DEBUGGING stuck-pending explanation attributes permanent orphaning to Record using $setOnInsert, and describes a replacement completion as a separate upsert. In contrast, both monitor callers invoke a completion operation, MongoStore RecordComplete delegates to UpdateStatus, and UpdateStatus uses $set on the same event_id/subscription_id predicate without an upsert option. Conditional on a later non-skipped completion reaching the store successfully while the row exists, that pending row can be updated; $setOnInsert on start does not itself make it permanently pending. (low confidence) [source 1] [source 2] [source 3] [source 4]
Children
- No children recorded.