feat(datastore): race-id DDS create (alternative to claims, v1 alpha)#27325
Draft
kian-thompson wants to merge 5 commits into
Draft
feat(datastore): race-id DDS create (alternative to claims, v1 alpha)#27325kian-thompson wants to merge 5 commits into
kian-thompson wants to merge 5 commits into
Conversation
…e to claims)
Adds the public API surface for race-id-tagged channel creation:
- IAttachMessage gains optional 'raceId' field (only emitted when document
schema indicates support; older clients in mixed sessions never see it).
- IFluidDataStoreRuntime.createChannel gains a new 3-argument overload:
createChannel(raceId, type, { onLost }). The overload is the opt-in for
race semantics; existing 2-arg call sites are unchanged.
- New OnRaceLost type and 'raceResolved' event.
Implementation follows in subsequent commits.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Core race resolution in FluidDataStoreRuntime:
- createChannel(raceId, type, raceOptions) overload mints unique
internal channel id (${raceId}#${guid}) and tracks the entry.
- Outbound IAttachMessage now carries optional raceId.
- processAttachMessages applies first-wins resolution across clients:
loser context is removed from contexts; loser->winner redirect is
recorded; onLost callback is scheduled via queueMicrotask.
- Inbound channel ops to known-loser channel ids are dropped on every
client via the loserToWinner map, keeping resolution deterministic.
- raceResolved event emitted for diagnostics.
v1 scope: summary persistence of redirects, doc-schema gate, tests,
and changeset still pending per plan.md.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Covers synchronous validation paths of the new 3-arg createChannel
overload: detached-state rejection, derived channel id format
(${raceId}#...), duplicate-raceId rejection per client, and empty
raceId rejection.
Full FWW resolution across two runtimes (inbound a-t-t-a-c-h ops,
loser context teardown, onLost scheduling) requires more harness
plumbing and is deferred to a follow-up.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Writes a '.races' top-level blob containing the loserToWinner map in FluidDataStoreRuntime.summarize() when the map is non-empty, and reads it back asynchronously during construction. This lets mid-session joiners drop late ops to historical losers deterministically once the load completes. v1 caveat: the read is best-effort and not awaited before op processing. Ops to historical losers may transiently be applied during the load window. Tracked as a follow-up. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Adds .changeset/race-id-dds-create.md describing the new alpha surface (raceId, OnRaceLost, raceResolved event) and v1 caveats. - Adds @Alpha overload declaration on FluidDataStoreRuntime.createChannel so the implementation's release tag matches the @Alpha OnRaceLost type it references (fixes ae-incompatible-release-tags). - Escapes '->' in tsdoc comments per tsdoc-escape-greater-than. - Regenerates api-report files for datastore-definitions, runtime-definitions, and datastore. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Contributor
|
Hi! Thank you for opening this PR. Want me to review it? Based on the diff (484 lines, 9 files), I've queued these reviewers:
How this works
|
Contributor
|
🔗 No broken links found! ✅ Your attention to detail is admirable. linkcheck output |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Alternative to PRs #27286 / #27291 (claims). Solves the "two clients racing to lazily create the same singleton DDS" problem at the DDS attach path instead of via a generic FWW key→value primitive. Preserves optimistic local application; only pays a cost when a race actually occurs.
This is v1, alpha-tagged, and intentionally narrow. Larger pieces (race-id handles, data-store-level races, async
onLost, publicIChannel.dispose()) are deferred to follow-ups.API surface (alpha)
The runtime mints a unique internal channel id (
${raceId}#${guid}) — racing clients agree only on the race id, not the channel id.Resolution semantics
FWW by sequenced attach-op order:
raceIdwins; its channel id is the canonical winner.raceIdare dropped.loserToWinnermap).onLost(loserChannel, winnerChannelId)fires (viaqueueMicrotask) so the app can salvage local edits before continuing on the winner channel.loserToWinneris persisted in a.racessummary blob so mid-session joiners drop late ops correctly.What's in this PR
c141675badaf797cFluidDataStoreRuntime68b5d4db3e8d85c1.racessummary blob (write + async rehydrate)314e2d96Build: green. Tests: 46/46 passing in
@fluidframework/datastore.v1 limitations / explicitly deferred
onLostto migrate.IChannel.dispose()— no public dispose; loser context is removed but apps must stop using the loser channel themselves.onLost— callback is sync (scheduled viaqueueMicrotask); merge work cannot be awaited by op processing.minVersionForCollabgate — older clients won't recognize theraceIdfield; relying on alpha tag + opt-in API for now. Recommended to add before GA.Follow-ups (tracked separately)
minVersionForCollabgate + back-compat testsComparison
vs. PR #27286 / #27291 (claims): claims add a general FWW key→value primitive at runtime or DDS level; consumers must restructure to read-before-create. This PR keeps optimistic create-first semantics and only forces app awareness when the race actually fires.
🤖 Generated with Copilot CLI
Co-authored-by: Copilot 223556219+Copilot@users.noreply.github.com