Skip to content

feat(claims-example): add example app demonstrating the Claims DDS#27573

Open
kian-thompson wants to merge 8 commits into
microsoft:mainfrom
kian-thompson:kian-thompson/claims-example-app
Open

feat(claims-example): add example app demonstrating the Claims DDS#27573
kian-thompson wants to merge 8 commits into
microsoft:mainfrom
kian-thompson:kian-thompson/claims-example-app

Conversation

@kian-thompson

@kian-thompson kian-thompson commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

Description

Adds a new @fluid-example/claims-example app that showcases the Claims DDS running inside a real Fluid container. The Claims DDS is currently an internal building block; the intent is for it to eventually live inside every PureDataObject. Until that API exists, this example wires it up by hand inside a custom ResourceManager data object to show the underlying mechanics.

The app runs two independent clients against an in-memory ordering service (LocalDeltaConnectionServer) — everything else is real (container runtime, ops roundtripping through the service, handle serialization across clients). It claims ownership of resources by binding claim keys to the IFluidHandle of other DDSes, across five scenarios:

  1. Claim a resource — client A creates a SharedMap and claims its handle.
  2. Cross-client read — client B resolves the claimed handle to the same resource.
  3. First-writer-wins — client B's competing claim is rejected.
  4. Race — two clients claim a fresh key concurrently; the ordering service picks the winner.
  5. Compare-and-swap — client A atomically reassigns a key to a new handle.

Each call site handles the Claims API (trySetClaim / compareAndSetClaim and the ClaimResult Pending lifecycle) directly, rather than through a wrapper, so the example reflects what real call-site usage patterns look like.

Reviewer Guidance

The review process is outlined on this wiki page.

This is opened as a draft. The Claims DDS has no public consumption path yet, so the example deliberately uses /internal entry points.

AB#74216

Add a new @fluid-example/claims-example app that showcases the Claims DDS
running inside a real Fluid container. A custom ResourceManager data object
hosts a Claims DDS and uses it to claim ownership of other DDSes by storing
their IFluidHandles as claim values, across five scenarios (claim, cross-client
read, first-writer-wins, race, compare-and-swap).

Each call site handles the Claims API (trySetClaim / compareAndSetClaim and the
ClaimResult Pending lifecycle) directly, rather than through a wrapper, so the
example reflects real call-site usage patterns.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actions

github-actions Bot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

Hi! Thank you for opening this PR. Want me to review it?

Based on the diff (1183 lines, 20 files), I've queued these reviewers:

  • Correctness — logic errors, race conditions, lifecycle issues
  • Security — vulnerabilities, secret exposure, injection
  • API Compatibility — breaking changes, release tags, type design
  • Performance — algorithmic regressions, memory leaks
  • Testing — coverage gaps, hollow tests

How this works

  • Adjust the reviewer set by ticking/unticking boxes above. Reviewer toggles alone don't trigger anything.

  • Tick Start review below to dispatch the review fleet.

  • After review finishes, tick Start review again to request another run — it auto-resets after each dispatch.

  • This comment updates as new commits land; your reviewer selections are preserved.

  • Start review

kian-thompson and others added 2 commits June 22, 2026 18:19
…check

@fluidframework/test-utils is in the Tests layer (packages/test/). Listing it
as a production dependency created an Examples -> Tests layer edge, closing a
cycle (Examples -> Tests -> Tools -> Examples) and failing `flub check layers`.
Match the convention used by every other example and depend on it as a
devDependency instead.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The CI build regenerates PACKAGES.md and fails if it differs from the committed
copy. Adding a new package requires regenerating it via `npm run generate:packagesMd`.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@kian-thompson kian-thompson marked this pull request as ready for review June 22, 2026 21:55

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot reviewed 6 out of 7 changed files in this pull request and generated no comments.

Files not reviewed (1)
  • pnpm-lock.yaml: Generated file

kian-thompson and others added 2 commits June 23, 2026 17:23
…ms package

The claims DDS was renamed from @fluidframework/claims to
@fluid-internal/claims and its /internal subpath export was removed.
Update the claims-example app's dependency and imports to match.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Comment thread examples/apps/claims-example/src/index.ts Outdated
kian-thompson and others added 3 commits June 29, 2026 19:14
Rework the claims example into a simple UI for claiming free-form string
keys. A single root ClaimsDataObject abstracts the Claims DDS behind a
trySetClaim method, pairing each key with a handle to a backing
SharedDirectory. Uses only trySetClaim (no CAS); on a lost race it
switches to the winner's handle. The view reacts to a claimsChanged event
to keep the owners table live.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actions

Copy link
Copy Markdown
Contributor

🔗 No broken links found! ✅

Your attention to detail is admirable.

linkcheck output

1: starting server using command "npm run serve -- --no-open"
and when url "[ 'http://127.0.0.1:3000' ]" is responding with HTTP status code 200
running tests using command "npm run check-links"


> fluid-framework-website@0.0.0 serve
> docusaurus serve --no-open

[SUCCESS] Serving "build" directory at: http://localhost:3000/

> fluid-framework-website@0.0.0 check-links
> linkcheck http://localhost:3000 --skip-file skipped-urls.txt

Crawling...

Stats:
  290753 links
    1929 destination URLs
    2179 URLs ignored
       0 warnings
       0 errors


@github-actions

Copy link
Copy Markdown
Contributor

Bundle size comparison

Base commit: 52d5ba6ae7c2031ad14864e8b64f8314f2552214
Head commit: 795822ea1f86bf1558d57eaf9593677e209f08e3

Notable changes

No bundles changed by ≥ 500 bytes parsed.

Per-bundle deltas

@fluid-example/bundle-size-tests

  • azureClient.js: parsed 619057 → 619113 (+56), gzip 164811 → 164858 (+47)
  • odspClient.js: parsed 591891 → 591947 (+56), gzip 158905 → 158947 (+42)
  • aqueduct.js: parsed 525587 → 525622 (+35), gzip 140709 → 140739 (+30)
  • fluidFramework.js: parsed 392450 → 392471 (+21), gzip 111413 → 111427 (+14)
  • sharedTree.js: parsed 381837 → 381851 (+14), gzip 108807 → 108817 (+10)
  • containerRuntime.js: parsed 303937 → 303951 (+14), gzip 83213 → 83221 (+8)
  • sharedString.js: parsed 175984 → 175991 (+7), gzip 49445 → 49453 (+8)
  • experimentalSharedTree.js: parsed 160798 → 160798 (0), gzip 45804 → 45804 (0)
  • matrix.js: parsed 159845 → 159852 (+7), gzip 45411 → 45418 (+7)
  • loader.js: parsed 145221 → 145235 (+14), gzip 39052 → 39067 (+15)
  • odspDriver.js: parsed 104431 → 104452 (+21), gzip 32647 → 32657 (+10)
  • directory.js: parsed 66616 → 66623 (+7), gzip 18532 → 18540 (+8)
  • 748.js: parsed 58793 → 58793 (0), gzip 17826 → 17826 (0)
  • map.js: parsed 46709 → 46716 (+7), gzip 14310 → 14317 (+7)
  • odspPrefetchSnapshot.js: parsed 45650 → 45664 (+14), gzip 15275 → 15284 (+9)
  • 594.js: parsed 44493 → 44493 (0), gzip 13744 → 13744 (0)
  • summarizerDelayLoadedModule.js: parsed 30753 → 30753 (0), gzip 7767 → 7767 (0)
  • socketModule.js: parsed 26486 → 26493 (+7), gzip 7883 → 7891 (+8)
  • createNewModule.js: parsed 12480 → 12480 (0), gzip 4786 → 4786 (0)
  • summaryModule.js: parsed 3797 → 3797 (0), gzip 1860 → 1860 (0)
  • connectionState.js: parsed 724 → 724 (0), gzip 429 → 429 (0)
  • sharedTreeAttributes.js: parsed 666 → 673 (+7), gzip 432 → 441 (+9)
  • debugAssert.js: parsed 429 → 429 (0), gzip 299 → 299 (0)
  • FluidFramework-HashFallback.js: parsed 422 → 422 (0), gzip 316 → 316 (0)

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants