Skip to content

Fix: Assign block tracking IDs via an atomic counter#37

Merged
taylortom merged 1 commit into
masterfrom
fix/duplicate-tracking-ids
Jun 9, 2026
Merged

Fix: Assign block tracking IDs via an atomic counter#37
taylortom merged 1 commit into
masterfrom
fix/duplicate-tracking-ids

Conversation

@taylortom

@taylortom taylortom commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Fixes #36

Fix

  • Replace the read-max-then-increment in insertTrackingId with allocation from a per-course atomic counter (findOneAndUpdate $inc), seeded once from the existing max. This bypasses the content DataCache (which is TTL-only with no write-invalidation), so rapid/sequential block inserts can no longer be handed duplicate _trackingIds — the root cause of Duplicate tracking IDs assigned to blocks #36 / #201.
  • All tracking-ID logic now lives in this module: the hook also fires once per payload during a bulk clone, so cloned blocks allocate here too. Multilang language replicas (flagged _multilangSync) intentionally reuse the source ID and are skipped.
  • Counter is stored in content's existing contentcounters collection, so course deletion cleans it up via content's existing sweep — no new collection or index.
  • resetCourseTrackingIds now reads/writes Mongo directly (cache-safe) and realigns the counter; it remains the canonical renumber routine.
  • Added adapt-authoring-mongodb peer dependency.

Breaking

  • None.

Testing

  • lib/SpoorTrackingModule.spec.js rewritten: covers allocation (seed + $inc, contiguous ranges), multilang skip, clone-payload overwrite, reset + counter realignment, and the handler. 16/16 pass; standard clean.

⚠️ Release ordering: this must release before or with the matching adapt-authoring-content PR. New spoortracking is compatible with old content, but new content (clone no longer allocates) regresses with old spoortracking.

insertTrackingId previously read the current max via content.find, which
is served by a TTL-only cache with no write-invalidation, so rapid
sequential block inserts could be handed duplicate IDs. Allocate from a
per-course atomic counter ($inc) that bypasses the cache, mirroring
friendly ID generation. All tracking-ID logic now lives in this module.

Refs cgkineo/adapt-authoring#201
@taylortom
taylortom merged commit 61f4294 into master Jun 9, 2026
1 of 2 checks passed
@taylortom
taylortom deleted the fix/duplicate-tracking-ids branch June 9, 2026 12:17
github-actions Bot pushed a commit that referenced this pull request Jun 9, 2026
## [1.2.2](v1.2.1...v1.2.2) (2026-06-09)

### Fix

* Assign block tracking IDs via an atomic counter (fixes #36) (#37) ([61f4294](61f4294)), closes [#36](#36) [#37](#37)
@github-actions

github-actions Bot commented Jun 9, 2026

Copy link
Copy Markdown

🎉 This PR is included in version 1.2.2 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Duplicate tracking IDs assigned to blocks

1 participant