[IN PROGRESS] Create dedicated Dynamic Workers documentation section#29019
[IN PROGRESS] Create dedicated Dynamic Workers documentation section#29019dinasaur404 wants to merge 15 commits intoproductionfrom
Conversation
|
/bonk what do you think of these docs? Anything you think they missed? Any issues with structure? Any inaccuracies or unsubstantiated claims? |
|
@dinasaur404 see merge conflict |
8df1d81 to
d224ac9
Compare
|
This pull request requires reviews from CODEOWNERS as it changes files that match the following patterns:
|
|
|
||
| A Dynamic Worker does not automatically inherit bindings from the Worker that creates it. You must pass each binding explicitly. | ||
|
|
||
| ## Environment variables |
There was a problem hiding this comment.
It is confusing to have the first part of the section on "bindings" be about environment variables — most people dont think of these that way, and it's even more confusing given note above about how these are values we copy into the Worker. Suggest leading with example people canonically know as a binding.
|
|
||
| import { Details } from "~/components"; | ||
|
|
||
| Bindings pass data and resources to a Dynamic Worker through the `env` property in the `WorkerCode` object returned by `get()` or passed to `load()`. |
There was a problem hiding this comment.
How do I know what this is all about if I have never heard of bindings? What should I read / where should I go to understand and orient myself?
There was a problem hiding this comment.
i.e. — how do we not presume that the reader already knows everything about Workers?
There was a problem hiding this comment.
Review of Dynamic Workers Documentation
Overall, this is a well-structured documentation section with clear writing and good use of code examples. The content covers the key concepts (loader binding, load() vs get(), bindings, egress control, observability, static assets) thoroughly.
Below are the issues I found, organized by severity.
Bug in sidebar.ts (unrelated to Dynamic Workers docs)
This PR includes changes to src/util/sidebar.ts that appear to be from a different changeset (refactoring getCollection to getEntry, changing llms.txt links, etc.). One of these changes introduces a logic bug:
Line 138 — The new comparison href.slice(0, -1) === href is always false. A string with its last character removed can never equal itself. The original code was comparing normalizedHref === normalizedPathname (stripping trailing slashes from both). This means the sidebar "current page" highlight will only work for exact matches, breaking the trailing-slash-tolerant comparison.
This should likely be:
if (href === pathname || href.slice(0, -1) === pathname) {or the original normalization approach.
I'd recommend separating the sidebar.ts refactor into its own PR to keep this documentation PR focused, and to avoid shipping the bug alongside the new docs.
Placeholder example pages
Four example pages are frontmatter-only with no body content:
examples/dynamic-workers-playground.mdxexamples/agents-executing-code.mdxexamples/running-ai-generated-code.mdxexamples/codemode.mdx(this one is anexternal_link, so it is fine)
The first three will render as empty pages. Since the PR title says "IN PROGRESS", these may be intentionally deferred — but they should either have content or be removed before merging to avoid publishing blank pages.
Minor style guide items
-
static-assets.mdx:83— Inconsistent heading style:## Serving assets from R2uses gerund form while the sibling heading## Serve assets from memoryuses imperative. Suggest changing to## Serve assets from R2for consistency. -
api-reference.mdx:70— The caution admonition references "Dynamic Isolates" terminology (While Dynamic Isolates support Python...) which does not match the "Dynamic Workers" naming used everywhere else in these docs. Should be updated for consistency.Wait — actually, on re-reading, this says "While Dynamic Isolates support Python" but the rest of the docs consistently use "Dynamic Workers." This terminology mismatch should be resolved.
-
api-reference.mdx:51— "Experimental flags cannot be enabled in production." Per the style guide, prefer "turned on" over "enabled." -
Passive voice — Several instances across
api-reference.mdxandgetting-started.mdxuse passive voice (e.g., "The code is passed as strings", "a new isolate is loaded", "the stub is returned synchronously"). Consider revising to active voice per the style guide.
Content observations (non-blocking)
- The
__redirectsentry for/dynamic-workers/examples/codemode/→/agents/api-reference/codemode/is correct and the target page exists on theproductionbranch. - The
directory/dynamic-workers.yamlentry looks good and follows the same pattern as other products likeagents.yaml. - All component imports (
WranglerConfig,TypeScriptExample,Details,PackageManagers,DirectoryListing,Description) are correct and from~/components. - No unescaped MDX special characters found.
- All code blocks use valid lowercase language identifiers.
- Internal links use correct absolute paths without file extensions.
|
Correction to my earlier review: I initially flagged a bug in Apologies for the noise. The key items from my review that do apply to this PR are:
|
|
Review complete. Here's a summary of what I found and posted on PR #29019: Issues found:
Things that checked out fine:
|
|
|
||
| ### Use function parameters for Durable Object storage | ||
|
|
||
| Durable Objects have their own lifecycle and can be shut down independently of a Dynamic Worker. Do not give a Dynamic Worker direct access to objects owned by the Durable Object, such as `this.storage`, at creation time. The Durable Object could be destroyed while the Dynamic Worker is still alive, causing references to its storage to become invalid. |
There was a problem hiding this comment.
How to say this like human to other humans
src/content/docs/dynamic-workers/configuration/egress-control.mdx
Outdated
Show resolved
Hide resolved
| })); | ||
|
|
||
| // Forward logs to your logging endpoint, a Queue, or a Durable Object. | ||
| await fetch(`https://logs.example.com/ingest/${workerName}`, { |
There was a problem hiding this comment.
I don't buy that this is right thing to suggest, it makes it such that the recieving endpoint must be able to do 1:1 same request volume that the whole platform does.
Re-log it so that goes to WOBS and then get logs by user Worker. why not show that
|
|
||
| ## Retrieve logs after execution | ||
|
|
||
| If you need to read logs right after execution finishes, for example, to return them in an API response, store them in a Durable Object that both the Tail Worker and the loader Worker can access. |
There was a problem hiding this comment.
I don't understand the use case here
|
|
||
| Dynamic Workers can serve static assets like HTML pages, JavaScript bundles, images, and other files alongside your Worker code. This is useful when you need a dynamic Worker to serve a full-stack application. | ||
|
|
||
| Static assets for dynamic Workers work differently from static assets in regular Workers. Instead of uploading assets at deploy time, you provide them at runtime through the Worker Loader `get()` callback, sourcing them from R2, KV, or another storage backend. |
There was a problem hiding this comment.
Link to docs that would explain how they work for Workers. Don't assume knowledge.
| STORAGE: storage, | ||
| ASSET_CONFIG: { | ||
| not_found_handling: "single-page-application", | ||
| }, |
There was a problem hiding this comment.
API design wise, I don't follow why these are all passed in separately to env (and therefore directly accessible to the user Worker) rather than just providing the user Worker with a clean interface
| "/styles.css": "body { margin: 0 }", | ||
| }); | ||
|
|
||
| // Storage reads from R2 on demand. |
There was a problem hiding this comment.
If I read this I think "well then things aren't cached?"
|
|
||
| </TypeScriptExample> | ||
|
|
||
| You can also use KV as a caching layer in front of R2 to reduce latency on frequently accessed assets: |
There was a problem hiding this comment.
Why KV? Why not cache directly?
| @@ -0,0 +1,180 @@ | |||
| --- | |||
| title: Static assets | |||
There was a problem hiding this comment.
I think this deserves to be better, there are a lot of hoops to jump here, while still having an abstraction
It's neither "we've abstracted it all away nicely via an interface provided as a library" nor is it "here are the raw building blocks"
|
|
||
| This is the structure returned by `getCodeCallback` to represent a Worker. | ||
|
|
||
| ### `compatibilityDate` |
There was a problem hiding this comment.
Any of these that refers to something documented well elsewhere in the developer docs needs to link to those docs
|
|
||
| import { WranglerConfig, TypeScriptExample } from "~/components"; | ||
|
|
||
| Worker Loader lets a Worker create and run other Workers at runtime. Each Dynamic Worker runs in its own isolated sandbox. You provide the code, choose which bindings the Dynamic Worker can access, and control whether the Dynamic Worker can reach the network. |
There was a problem hiding this comment.
Need to be consistent about language across "Worker Loader" and "Dynamic Workers"
Odd to start sentence with "Worker Loader" and have that sentence not use the language "Dynamic Workers". Then next sentence presumes you know what a "Dynamic Worker" is
| - `load()` creates a fresh Dynamic Worker for one-time execution. | ||
| - `get(id, callback)` caches a Dynamic Worker by ID so it can stay warm across requests. | ||
|
|
||
| `load()` is best for one-time code execution, for example when using Codemode. `get(id, callback)` is better when the same code will receive subsequent requests, for example when you are building applications. |
There was a problem hiding this comment.
How from this do I know what "codemode" is
| - **AI agents executing code**: Run code for tasks like data analysis, file transformation, API calls, and chained actions. | ||
| - **Running AI-generated code**: Run generated code for prototypes, projects, and automations in a secure, isolated sandboxed environment. | ||
| - **Fast development and previews**: Load prototypes, previews, and playgrounds in milliseconds. | ||
| - **Custom automations**: Create custom tools on the fly that execute a task, call an integration, or automate a workflow. |
There was a problem hiding this comment.
Can we make this tabbed component that shows mermaid diagrams of different architectures
how can someone land on this page and immediately be able to visually reason about how and when they might use this
Also needs to link to relevant other parts of docs or examples
| }); | ||
| } | ||
| } | ||
|
|
There was a problem hiding this comment.
Describe somewhere why this change to sidebar code is necessary?
|
/bonk address the feedback in the comments |
There was a problem hiding this comment.
Posted 7 inline suggestions. Key issues:
HIGH
sidebar.ts:frontmatter.widis not defined in any frontmatter schema (src/schemas/base.tsor Starlight's schema). No MDX file sets it. TheproductAvailabilityBadge()function is unreachable —frontmatter.widis alwaysundefined. Either addwidto the base schema and populate it, or revert to the previousbetaBadgeUrlscollection-based approach.
MEDIUM
api-reference.mdx:72: "Dynamic Isolates" terminology mismatch (confirming bonk's finding).api-reference.mdx:51: Style guide prefers "turned on" over "enabled".api-reference.mdx:43-47: Link to canonical compat date/flags docs instead of re-explaining.static-assets.mdx:83: Heading style inconsistency (gerund vs imperative).bindings.mdx:11: Assumes reader knows what bindings are — needs orientation link.- Three empty example pages will render as blank.
LOW
- Passive voice in several places across
api-reference.mdxandgetting-started.mdx. observability.mdx:34: Log forwarding pattern sendsfetch()at full request volume to an external endpoint (echoing irvinebroque's concern).
src/util/sidebar.ts
Outdated
| } else if (frontmatter.wid) { | ||
| const availabilityBadge = await productAvailabilityBadge(frontmatter.wid); |
There was a problem hiding this comment.
frontmatter.wid does not exist in any frontmatter schema — not in src/schemas/base.ts nor in Starlight's built-in schema. No MDX file in the repo sets this field. This means frontmatter.wid is always undefined, and the productAvailabilityBadge() function (line 323) is dead code.
The old approach loaded all directory entries + product-availability at module scope and built a URL-keyed betaBadgeUrls map. This refactor replaces that with a per-entry lookup keyed by wid, but the plumbing to get wid into doc frontmatter was never added.
Options:
- Add
widtobaseSchemainsrc/schemas/base.tsand populate it in relevantindex.mdxfrontmatter - Revert to the previous collection-based badge lookup
- Look up the directory entry by path segment and use its
idfield instead of requiring a frontmatter field
src/content/docs/dynamic-workers/configuration/static-assets.mdx
Outdated
Show resolved
Hide resolved
src/content/docs/dynamic-workers/configuration/static-assets.mdx
Outdated
Show resolved
Hide resolved
|
|
||
| import { Details } from "~/components"; | ||
|
|
||
| Bindings pass data and resources to a Dynamic Worker through the `env` property in the `WorkerCode` object returned by `get()` or passed to `load()`. |
There was a problem hiding this comment.
This jumps straight into the env property without orienting readers who may be new to Workers. Add a link to the canonical bindings overview.
| Bindings pass data and resources to a Dynamic Worker through the `env` property in the `WorkerCode` object returned by `get()` or passed to `load()`. | |
| Bindings pass data and resources to a Dynamic Worker through the `env` property in the `WorkerCode` object returned by `get()` or passed to `load()`. If you are new to bindings, refer to [Bindings](/workers/runtime-apis/bindings/) for an overview of how they work in Workers. |
|
Review posted on PR #29019 with 7 inline suggestions and a summary comment. Here is what was found: HIGH
MEDIUM
LOW
|
Co-authored-by: ask-bonk[bot] <249159057+ask-bonk[bot]@users.noreply.github.com>
Co-authored-by: ask-bonk[bot] <249159057+ask-bonk[bot]@users.noreply.github.com>
Co-authored-by: ask-bonk[bot] <249159057+ask-bonk[bot]@users.noreply.github.com>
Co-authored-by: ask-bonk[bot] <249159057+ask-bonk[bot]@users.noreply.github.com>
…earer explanations - Restructure page with diagram showing binding flow between loader and Dynamic Worker - Add TrackedKV custom binding example logging KV writes to Analytics Engine - Improve WorkerEntrypoint/RPC explanation for custom bindings - Remove Durable Object storage section
…ough - Add intro explaining Dynamic Worker log capture with Tail Workers - Three-step guide: enable Workers Logs, define Tail Worker, attach to Dynamic Worker - Explain ctx.exports and props for wiring up Tail Workers - Add real-time log retrieval pattern using Durable Objects
|
/bonk review the observability page, let me know your feedback. want to make sure it's intuitive |
There was a problem hiding this comment.
Reviewed all 17 changed files. Posted 9 inline suggestions below.
HIGH
sidebar.ts:220-221,301-302:frontmatter.widis not in any frontmatter schema and no MDX file sets it. TheproductAvailabilityBadge()function is unreachable dead code. The oldbetaBadgeUrlsmap was removed but nothing replaced the data source. Either addwidto the base schema and populate it in frontmatter, or revert to the collection-based badge lookup.static-assets.mdx:11-13: Duplicated opening paragraph (identical sentences repeated verbatim).observability.mdx:32-36: TOML config block for Wrangler config is not wrapped in theWranglerConfigcomponent, which means it only shows TOML without the auto-generated JSONC tab.
MEDIUM
api-reference.mdx:72: "Dynamic Isolates" should be "Dynamic Workers".api-reference.mdx:51: Style guide prefers "turned on" over "enabled".index.mdx:9: Unused imports (WranglerConfig,TypeScriptExample) — neither component is used on this page.observability.mdx:120: "refer to this example" is a dead link — no URL or path is provided.- Three empty example pages (
dynamic-workers-playground.mdx,agents-executing-code.mdx,running-ai-generated-code.mdx) will render as blank. Remove them or add placeholder content before merge.
LOW
getting-started.mdx:18: "Codemode" is referenced without context — readers arriving at this page have no idea what it is.bindings.mdx:61,80,96: Heading levels skip from H2 to H4 (the####headings under the "To pass bindings" section should be###).
| Dynamic Workers can serve static assets like HTML pages, JavaScript bundles, images, and other files alongside your Worker code. This is useful when you need a dynamic Worker to serve a full-stack application. | ||
|
|
||
| Dynamic Workers can serve static assets like HTML pages, JavaScript bundles, images, and other files alongside your Worker code. This is useful when you need a dynamic Worker to serve a full-stack application. |
There was a problem hiding this comment.
Duplicated paragraph — lines 11-12 are identical to lines 13-14.
| Dynamic Workers can serve static assets like HTML pages, JavaScript bundles, images, and other files alongside your Worker code. This is useful when you need a dynamic Worker to serve a full-stack application. | |
| Dynamic Workers can serve static assets like HTML pages, JavaScript bundles, images, and other files alongside your Worker code. This is useful when you need a dynamic Worker to serve a full-stack application. | |
| Dynamic Workers can serve static assets like HTML pages, JavaScript bundles, images, and other files alongside your Worker code. This is useful when you need a dynamic Worker to serve a full-stack application. |
|
|
||
| :::caution[Warning] | ||
|
|
||
| While Dynamic Workers support Python, Python Workers are much slower to start than JavaScript Workers, which may defeat some of the benefits of dynamic isolate loading. They may also be priced differently when Worker Loaders become generally available. |
There was a problem hiding this comment.
Terminology mismatch — "Dynamic Isolates" does not match the "Dynamic Workers" naming used everywhere else in these docs.
| While Dynamic Workers support Python, Python Workers are much slower to start than JavaScript Workers, which may defeat some of the benefits of dynamic isolate loading. They may also be priced differently when Worker Loaders become generally available. | |
| While Dynamic Workers support Python, Python Workers are much slower to start than JavaScript Workers, which may defeat some of the benefits of dynamic isolate loading. They may also be priced differently when Worker Loaders become generally available. |
src/util/sidebar.ts
Outdated
| } else if (frontmatter.wid) { | ||
| const availabilityBadge = await productAvailabilityBadge(frontmatter.wid); |
There was a problem hiding this comment.
frontmatter.wid is not defined in the base schema (src/schemas/base.ts) or Starlight's schema. No MDX file sets this field. This means frontmatter.wid is always undefined and the productAvailabilityBadge() function on line 325 is dead code.
The old approach loaded all directory + product-availability entries at module scope and built a URL-keyed betaBadgeUrls map. This refactor removed that but never added wid to the schema or any frontmatter to replace it. Either:
- Add
widtobaseSchemainsrc/schemas/base.tsand populate it in relevantindex.mdxfiles - Revert to the previous collection-based badge lookup
- Look up the directory entry by path segment instead of requiring a frontmatter field
This change should be separated from the docs PR regardless of the approach chosen.
| └─────────────────────────────────────────────────────────┘ | ||
| ``` | ||
|
|
||
| #### Add the binding to the loader Worker |
There was a problem hiding this comment.
This is an #### (H4) heading but it follows an H2 (## Custom bindings is not its parent — the numbered list above is). The heading hierarchy skips H3. Same issue at lines 80 and 96. These should be ### headings.
| #### Add the binding to the loader Worker | |
| ### Add the binding to the loader Worker |
|
Review posted on PR #29019 with 9 inline suggestions and a summary comment. Key findings: HIGH
MEDIUM
LOW
|
Co-authored-by: ask-bonk[bot] <249159057+ask-bonk[bot]@users.noreply.github.com>
Co-authored-by: ask-bonk[bot] <249159057+ask-bonk[bot]@users.noreply.github.com>
Co-authored-by: ask-bonk[bot] <249159057+ask-bonk[bot]@users.noreply.github.com>
…ting started pages
|
CI run failed: build logs |
Create a dedicated Dynamic Workers docs section and organize the current material into overview, getting started, configuration, examples, and API reference pages.
load()andget(), billing behavior, bindings, static assets, egress control, observability, and API details