setName() as the sanctioned bootstrap API for non-idFromName DOs#383
Merged
Conversation
For DOs where `ctx.id.name` is undefined (Cloudflare Agents facets and
similar framework-level bootstrap patterns), `setName(name)` now writes
the name to the legacy `__ps_name` storage key in addition to stashing
it in memory. This makes `setName()` the sanctioned bootstrap API:
frameworks no longer need to write `__ps_name` directly themselves —
PartyServer manages its own storage layout.
For DOs addressed via idFromName/getByName, behavior is unchanged:
ctx.id.name carries the name, no storage write happens.
Migration for framework authors who currently do:
await this.ctx.storage.put("__ps_name", name);
await this.__unsafe_ensureInitialized();
becomes:
await this.setName(name);
Backward compatible — the existing direct-storage pattern keeps working
since the storage write becomes idempotent.
Adds SetNameBootstrapServer + 3 tests covering:
1. setName() persists __ps_name for newUniqueId DOs
2. Cold-wake fetch recovers the name via the storage fallback
3. setName() does NOT write storage when ctx.id.name is set (regression
guard for the 0.5.0 zero-storage-write win on the happy path)
Made-with: Cursor
🦋 Changeset detectedLatest commit: 4db230a The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
hono-party
partyfn
partyserver
partysocket
partysub
partysync
partytracks
partywhen
y-partyserver
commit: |
If `ctx.storage.put(NAME_STORAGE_KEY, name)` throws, the previous ordering (set #_name first, then write) left an inconsistent in-memory state: `this.name` returned the new name but storage was empty. A retry of `setName(name)` would silently no-op the storage write (because the already-set #_name caused the bootstrap branch to be skipped), leaving the DO inconsistent until eviction. Reorder: write storage first, then assign #_name. If storage throws, Made-with: Cursor #_name stays undefined and the retry re-attempts the storage write.
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.
Summary
Follow-up to #381 (the 0.5.1 facet hydrate fix). Where #381 made the runtime path tolerate frameworks bootstrapping via direct
__ps_namestorage writes, this PR makes the API path clean:setName()itself now persists the name, so frameworks no longer need to reach into PartyServer's private storage layout.When
ctx.id.nameis undefined (e.g. Cloudflare Agents facets, spawned viactx.facets.get(...)rather thanidFromName()),setName(name)now:#_name(existing behavior)__ps_namestorage (new), so cold-wake invocations recover the name through#ensureInitialized()'s legacy storage fallbackWhen
ctx.id.nameis defined (the happy path foridFromName/getByNameDOs),setName()continues to NOT write storage —ctx.id.nameis the source of truth.Migration for framework authors
Cloudflare Agents currently does (in
_cf_initAsFacet):Once Agents bumps to this release, they can simplify to:
Migration is optional. The existing direct-storage-write pattern keeps working — the storage write just becomes idempotent with what
setName()would do.Test plan
SetNameBootstrapServer+ 3 tests:setName()on anewUniqueId()DO persists__ps_nameto storage (verified by reading storage back)setName()does NOT write storage whenctx.id.nameis set (regression guard for the 0.5.0 zero-storage-write win)setName()migrationLong-term context
Workerd-team work (Option F in the discussion thread) will eventually expose
ctx.id.namefor facets natively, at which pointsetName()becomes redundant for facets too. Until then,setName()is the supported bootstrap primitive.Made with Cursor