Skip to content

Commit 27cd37a

Browse files
committed
Clarify expected interaction between Worker Versions and Durable Objects migrations
1 parent eeb4aad commit 27cd37a

File tree

2 files changed

+63
-39
lines changed

2 files changed

+63
-39
lines changed

src/content/docs/durable-objects/reference/durable-objects-migrations.mdx

Lines changed: 48 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -36,22 +36,22 @@ To apply a Create migration:
3636
<Steps>
3737
1. Add the following lines to your `wrangler.toml / wrangler.json` file:
3838

39-
<WranglerConfig>
40-
```toml
41-
[[migrations]]
42-
tag = "<v1>" # Migration identifier. This should be unique for each migration entry
43-
new_classes = ["<NewDurableObjectClass>"] # Array of new classes
44-
# For SQLite storage backend use new_sqlite_classes=["<NewDurableObjectClass>"] instead
45-
```
46-
</WranglerConfig>
47-
The Create migration contains:
48-
49-
- A `tag` to identify the migration.
50-
- The array `new_classes`, which contains the new Durable Object class.
39+
<WranglerConfig>
40+
```toml
41+
[[migrations]]
42+
tag = "<v1>" # Migration identifier. This should be unique for each migration entry
43+
new_classes = ["<NewDurableObjectClass>"] # Array of new classes
44+
# For SQLite storage backend use new_sqlite_classes=["<NewDurableObjectClass>"] instead
45+
```
46+
</WranglerConfig>
47+
The Create migration contains:
48+
49+
- A `tag` to identify the migration.
50+
- The array `new_classes`, which contains the new Durable Object class.
5151

5252
2. Ensure you reference the correct name of the Durable Object class in your Worker code.
5353
3. Deploy the Worker.
54-
</Steps>
54+
</Steps>
5555

5656
<Details header="Create migration example">
5757

@@ -65,10 +65,12 @@ name = "DURABLE_OBJECT_A"
6565
class_name = "DurableObjectAClass"
6666

6767
# Add the lines below for a Create migration.
68+
6869
[[migrations]]
6970
tag = "v1"
7071
new_classes = ["DurableObjectAClass"]
71-
```
72+
73+
````
7274
</WranglerConfig>
7375

7476
</Details>
@@ -115,7 +117,8 @@ To delete a Durable Object binding `DEPRECATED_OBJECT`, your `wrangler.toml / wr
115117
[[migrations]]
116118
tag = "v3" # Should be unique for each entry
117119
deleted_classes = ["DeprecatedObjectClass"] # Array of new classes
118-
```
120+
````
121+
119122
</WranglerConfig>
120123
</Details>
121124

@@ -128,26 +131,27 @@ To apply a Rename migration:
128131
<Steps>
129132
1. Update the previous class name to the new class name by editing your `wrangler.toml / wrangler.json` file in the following way:
130133

131-
<WranglerConfig>
132-
```toml
133-
[[durable_objects.bindings]]
134-
name = "<MY_DURABLE_OBJECT>"
135-
class_name = "<UpdatedDurableObject>" # Update the class name to the new class name
134+
<WranglerConfig>
135+
```toml
136+
[[durable_objects.bindings]]
137+
name = "<MY_DURABLE_OBJECT>"
138+
class_name = "<UpdatedDurableObject>" # Update the class name to the new class name
136139

137-
[[migrations]]
138-
tag = "<v3>" # Migration identifier. This should be unique for each migration entry
139-
renamed_classes = [{from = "<OldDurableObject>", to = "<UpdatedDurableObject>" }] # Array of rename directives
140-
```
141-
</WranglerConfig>
140+
[[migrations]]
141+
tag = "<v3>" # Migration identifier. This should be unique for each migration entry
142+
renamed_classes = [{from = "<OldDurableObject>", to = "<UpdatedDurableObject>" }] # Array of rename directives
143+
```
144+
</WranglerConfig>
145+
146+
The Rename migration contains:
147+
- A `tag` to identify the migration.
148+
- The `renamed_classes` array, which contains objects with `from` and `to` properties.
149+
- `from` property is the old Durable Object class name.
150+
- `to` property is the renamed Durable Object class name.
142151

143-
The Rename migration contains:
144-
- A `tag` to identify the migration.
145-
- The `renamed_classes` array, which contains objects with `from` and `to` properties.
146-
- `from` property is the old Durable Object class name.
147-
- `to` property is the renamed Durable Object class name.
148152
2. Reference the new Durable Object class name in your Worker code.
149153
3. Deploy the Worker.
150-
</Steps>
154+
</Steps>
151155

152156
<Details header = "Rename migration example">
153157

@@ -162,10 +166,12 @@ name = "MY_DURABLE_OBJECT"
162166
class_name = "UpdatedName"
163167

164168
# Renaming classes
169+
165170
[[migrations]]
166171
tag = "v3"
167172
renamed_classes = [{from = "OldName", to = "UpdatedName" }] # Array of rename directives
168-
```
173+
174+
````
169175
</WranglerConfig>
170176

171177
</Details>
@@ -221,7 +227,8 @@ class_name = "TransferredClass"
221227
[[migrations]]
222228
tag = "v4"
223229
transferred_classes = [{from = "DurableObjectExample", from_script = "OldWorkerScript", to = "TransferredClass" }]
224-
```
230+
````
231+
225232
</WranglerConfig>
226233

227234
</Details>
@@ -240,20 +247,21 @@ transferred_classes = [{from = "DurableObjectExample", from_script = "OldWorkerS
240247
- Each migration in the list can have multiple directives, and multiple migrations can be specified as your project grows in complexity.
241248

242249
:::caution[Important]
250+
243251
- The destination class (the class that stored Durable Objects are being transferred to) for a Rename or Transfer migration must be exported by the deployed Worker.
244252

245253
- You should not create the destination Durable Object class before running a Rename or Transfer migration. The migration will create the destination class for you.
246254

247255
- After a Rename or Transfer migration, requests to the destination Durable Object class will have access to the source Durable Object's stored data.
248256

249257
- After a migration, any existing bindings to the original Durable Object class (for example, from other Workers) will automatically forward to the updated destination class. However, any Workers bound to the updated Durable Object class must update their Durable Object binding configuration in the `wrangler` configuration file for their next deployment.
250-
:::
258+
:::
251259

252260
:::note
253261
Note that `.toml` files do not allow line breaks in inline tables (the `{key = "value"}` syntax), but line breaks in the surrounding inline array are acceptable.
254262
:::
255263

256-
{/* ## Examples of Durable Object migration
264+
{/\* ## Examples of Durable Object migration
257265

258266
To illustrate an example migrations workflow, the `DurableObjectExample` class can be initially defined with:
259267

@@ -268,7 +276,7 @@ new_classes = ["DurableObjectExample"] # Array of new classes
268276

269277
</WranglerConfig>
270278

271-
You can rename the `DurableObjectExample` class to `UpdatedName` and delete an outdated `DeprecatedClass` entirely. You can create separate migrations for each operation, or combine them into a single migration as shown below. */}
279+
You can rename the `DurableObjectExample` class to `UpdatedName` and delete an outdated `DeprecatedClass` entirely. You can create separate migrations for each operation, or combine them into a single migration as shown below. \*/}
272280

273281
## Enable SQLite storage backend on new Durable Object class migration
274282

@@ -293,3 +301,7 @@ new_sqlite_classes = ["MyDurableObject"] # Array of new classes
293301
For an example of a new class migration, refer to [Get started: Configure Durable Object class with SQLite storage backend](/durable-objects/get-started/tutorial-with-sql-api/#6-configure-durable-object-class-with-sqlite-storage-backend).
294302

295303
You cannot enable a SQLite storage backend on an existing, deployed Durable Object class, so setting `new_sqlite_classes` on later migrations will fail with an error. Automatic migration of deployed classes from their key-value storage backend to SQLite storage backend will be available in the future.
304+
305+
:::caution[Important]
306+
Durable Object migrations are atomic operations and cannot be gradually deployed. To provide early feedback to developers, new Worker versions with new migrations cannot be uploaded. Read through [Gradual deployments for Durable Objects](/workers/configuration/versions-and-deployments/gradual-deployments/#gradual-deployments-for-durable-objects) for more information.
307+
:::

src/content/docs/workers/configuration/versions-and-deployments/gradual-deployments.mdx

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -197,9 +197,9 @@ curl -s https://example.com -H 'Cloudflare-Workers-Version-Overrides: my-worker-
197197

198198
## Gradual deployments for Durable Objects
199199

200-
Due to [global uniqueness](/durable-objects/platform/known-issues/#global-uniqueness), only one version of each [Durable Object](/durable-objects/) can run at a time. This means that gradual deployments work slightly differently for Durable Objects.
200+
To provide [global uniqueness](/durable-objects/platform/known-issues/#global-uniqueness), only one version of each [Durable Object](/durable-objects/) can run at a time. This means that gradual deployments work slightly differently for Durable Objects.
201201

202-
When you create a new gradual deployment for a Durable Object Worker, each Durable Object is assigned a Worker version based on the percentages you configured in your [deployment](/workers/configuration/versions-and-deployments/#deployments). This version will not change until you create a new deployment.
202+
When you create a new gradual deployment for a Worker with Durable Objects, each Durable Object is assigned a Worker version based on the percentages you configured in your [deployment](/workers/configuration/versions-and-deployments/#deployments). This version will not change until you create a new deployment.
203203

204204
![Gradual Deployments Durable Objects](~/assets/images/workers/platform/versions-and-deployments/durable-objects.png)
205205

@@ -226,12 +226,24 @@ This is only an example, so the versions assigned to your Durable Objects may be
226226

227227
:::note
228228

229-
Typically, your Durable Object Worker will define both your Durable Object class and the Worker that interacts with it. In this case, you cannot deploy changes to your Durable Object and its Worker independently.
229+
Typically, a Worker bundle will define both the Durable Object class and a Worker that interacts with it. In this case, you cannot deploy changes to your Durable Object and its Worker independently.
230230

231231
You should ensure that API changes between your Durable Object and its Worker are [forwards and backwards compatible](/durable-objects/platform/known-issues/#code-updates) whether you are using gradual deployments or not. However, using gradual deployments will make it even more likely that different versions of your Durable Objects and its Worker will interact with each other.
232232

233233
:::
234234

235+
### Migrations
236+
237+
Versions of Worker bundles containing new Durable Object migrations cannot be uploaded. This is because Durable Object migrations are atomic operations. Durable Object migrations can be deployed with the following command:
238+
239+
```sh
240+
npx wrangler versions deploy
241+
```
242+
243+
In order to limit the blast radius of Durable Object migration deployments, migrations should be deployed independently of other code changes.
244+
245+
To understand why Durable Object migrations are atomic operations, consider the hypothetical example of gradually deploying a delete migration. If a delete migration were applied to 50% of Durable Object instances, then Workers requesting those Durable Object instances would fail because they would have been deleted. To do this without producing errors, a version of the Worker which does not depend on any Durable Object instances would have to have already been rolled out. At which point you can deploy a delete migration without affecting any traffic and there is no reason to do so gradually.
246+
235247
## Observability
236248

237249
When using gradual deployments, you may want to attribute Workers invocations to a specific version in order to get visibility into the impact of deploying new versions.

0 commit comments

Comments
 (0)