Skip to content

Reduce bounded sequence-assignment allocator round trips #1322

Description

@JackWilb

Summary

PR #1311 replaces unbounded sequence-assignment collection scans with race-safe bounded allocation. Private-session HAR profiling still shows multiple serialized provider round trips for a fresh participant: participant and allocator reads, rejected-slot lookup, transaction re-reads or compare-and-swap work, and the final commit.

Reduce these remaining round trips without weakening atomic assignment, rejected-slot reuse, or compatibility with existing studies.

Design direction

Keep assignment atomicity as table stakes. Potential provider-specific approaches include:

  • Maintain the next reusable/rejected slot or a bounded reusable-slot queue in allocator metadata.
  • Select and claim a reusable slot inside the same transaction or database function that reserves the participant's indexes.
  • Return the committed assignment and any required completion/bootstrap information from the allocation operation.
  • Avoid a pre-query whose result must be read again inside the transaction when provider capabilities offer a safer single-operation alternative.

Firebase and Supabase implementations may differ, but they must expose the same storage-engine semantics. LocalStorage remains the regression baseline.

Requirements

  • Preserve unique, monotonically correct sequenceIndex and creationIndex allocation under simultaneous starts.
  • Preserve rejected-assignment reuse order and prevent two participants from claiming the same rejected slot.
  • Keep every provider operation bounded; do not reintroduce assignment collection scans.
  • Retain lazy compatibility with assignments and allocator state created before Improve study startup assignment performance #1311.
  • Minimize serialized network request/response cycles on the fresh-participant path.
  • Define retry/conflict behavior and a bounded failure mode under sustained contention.
  • Do not allow a failed participant-record write to silently consume or orphan allocator state without recoverable handling.

Acceptance criteria

  • The Firebase fresh-participant path uses the minimum practical bounded transaction/read sequence, documented with a request trace.
  • The Supabase fresh-participant path uses the minimum practical compare-and-swap/database-operation sequence, documented with a request trace.
  • Reusable-slot selection does not require a separate unbounded query or scan.
  • Concurrent-start tests verify unique indexes and single-claim rejected-slot behavior under contention.
  • Legacy allocator initialization and legacy rejected assignments remain supported without manual migration.
  • Provider operation-count tests lock the permitted reads, queries, retries, and commits for fresh, existing, rejected-reuse, and conflict paths.
  • Before/after HAR timing is recorded against Firebase and Supabase where available.
  • yarn unittest --run, yarn typecheck, yarn lint, and yarn build pass.

Out of scope

Activity

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

Metadata

Metadata

Assignees

Labels

SpecifiedIssue has enough detail to implementbugSomething isn't working

Type

No type

Projects

  • Status
    Todo

Relationships

None yet

Development

No branches or pull requests

Issue actions