From cfaa7465f605142109c5b5366d4f779e2b045895 Mon Sep 17 00:00:00 2001 From: Joshua Howard Date: Thu, 10 Oct 2024 10:33:20 -0500 Subject: [PATCH 01/10] Add reference documentation for DurableObjectState --- .../docs/durable-objects/api/state.mdx | 282 ++++++++++++++++++ .../docs/durable-objects/api/websockets.mdx | 68 ++++- .../reference/in-memory-state.mdx | 53 +--- .../durable-objects/reference/websockets.mdx | 19 +- 4 files changed, 355 insertions(+), 67 deletions(-) create mode 100644 src/content/docs/durable-objects/api/state.mdx diff --git a/src/content/docs/durable-objects/api/state.mdx b/src/content/docs/durable-objects/api/state.mdx new file mode 100644 index 000000000000000..fbe197cece7eebb --- /dev/null +++ b/src/content/docs/durable-objects/api/state.mdx @@ -0,0 +1,282 @@ +--- +title: Durable Object State +pcx_content_type: concept +sidebar: + order: 4 +--- + +import { Tabs, TabItem } from "~/components"; + +## Description + +The `DurableObjectState` interface is accessible as an instance property on the Durable Objects class. This interface encapsulates methods that modify the state of a Durable Object, for example which WebSockets are attached to a Durable Object instance or how the runtime should handle concurrent Durable Object requests. + +The `DurableObjectState` interface is different that the [Storage API](/durable-objects/api/storage-api) in that it does not have top level methods which manipulate persistant application data. These methods are instead encapsulated in the [`DurableObjectStorage`](/durable-objects/api/storage-api) interface and accessed by [`DurableObjectState::storage`](/durable-objects/api/state/#storage). + + + +```js +import { DurableObject } from "cloudflare:workers"; + +// Durable Object +export class MyDurableObject extends DurableObject { + // DurableObjectState is accessible via the ctx instance property + constructor(ctx, env) { + super(ctx, env); + } + ... +} +``` + + + +```ts +import { DurableObject } from "cloudflare:workers"; + +export interface Env { + MY_DURABLE_OBJECT: DurableObjectNamespace; +} + +// Durable Object +export class MyDurableObject extends DurableObject { + // DurableObjectState is accessible via the ctx instance property + constructor(ctx: DurableObjectState, env: Env) { + super(ctx, env); + } + ... +} +``` + + + +## Methods + +### `waitUntil` + +`waitUntil` waits until the promise which is passed as a parameter resolves and can extends an event context up to 30 seconds after the last client disconnects. + +:::note[`waitUntil` is not necessary] + +The event context for a Durable Objects extends at least 60 seconds after the last client disconnects. So `waitUntil` is not necessary. It remains part of the `DurableObjectState` interface to remain compatible with [Workers Runtime APIs](/workers/runtime-apis/context/#waituntil). + +::: + +#### Parameters + +- A required promise of any type. + +#### Return values + +- None. + +### `blockConcurrencyWhile` + +`blockConcurrencyWhile` executes an async callback while blocking any other events from being delivered to the Durable Object instance until the callback completes. This method guarantees ordering and prevents concurrent requests. All events that were not explicitly initiated as part of the callback itself will be blocked. Once the callback completes, All other events will be delivered. + +`blockConcurrencyWhile` is commonly used within the constructor of the Durable Object class to enforce that initialization must occur before any requests are delivered. Another use case is executing `async` operations based on the current state of the Durable Object instance and using `blockConcurrencyWhile` to prevent that state from changing while yeilding the event loop. + +If the callback throws an exception, the object will be terminated and reset. This ensures that the object cannot be left stuck in an uninitialized state if something fails unexpectedly. To avoid this behavior, enclose the body of your callback in a `try...catch` block to ensure it cannot throw an exception. + +To help mitigate deadlocks there is a 30s timeout applied when executing the callback. If this timeout is exceeded the Durable Object instance will be reset. It is best practice to have the callback do as little work as possible to improve overall request throughput to the Durable Object instance. + +```js +// Durable Object +export class MyDurableObject extends DurableObject { + initialized = false; + + constructor(ctx, env) { + super(ctx, env); + + // blockConcurrencyWhile will ensure that initialized will always be true + this.ctx.blockConcurrencyWhile(async () => { + this.initialized = true; + }); + } + ... +} +``` + +#### Parameters + +- A required callback which returns a `Promise`. + +#### Return values + +- A `Promise` returned by the callback. + +### `acceptWebSocket` + +`acceptWebSocket` is part of the [WebSocket Hibernation API](durable-objects/reference/websockets/#websocket-hibernation), which allows a Durable Object instance to be removed from memory to save costs while keeping its WebSockets connected. + +`acceptWebSocket` adds a WebSocket to the set of WebSockets attached to the Durable Object instance. Once called, any incoming messages will be delivered by calling the Durable Object’s `webSocketMessage` handler, and `webSocketClose` will be invoked upon disconnect. After calling `acceptWebSocket`, the WebSocket is accepted and its `send` and `close` methods can be used. + +The [WebSocket Hibernation API](durable-objects/reference/websockets/#websocket-hibernation) takes the place of the standard [WebSockets API](/workers/runtime-apis/websockets/). Therefore, `ws.accept` must not have been called separately and `ws.addEventListener` method will not receive events as they will instead be delivered to the Durable Object. + +The WebSocket Hibernation API permits a maximum of 32,768 WebSocket connections per Durable Object instance, but the CPU and memory usage of a given workload may further limit the practical number of simultaneous connections. + +#### Parameters + +- A required `WebSocket` with name `ws`. +- An optional `Array` of associated tags. Tags can be used to retrieve WebSockets via [`DurableObjectState::getWebSockets`](/durable-objects/api/state/#getwebsockets). Each tag is a maximum of 256 characters and there can be at most 10 tags associated with a WebSocket. + +#### Return values + +- None. + +### `getWebSockets` + +`getWebSockets` is part of the [WebSocket Hibernation API](durable-objects/reference/websockets/#websocket-hibernation), which allows a Durable Object instance to be removed from memory to save costs while keeping its WebSockets connected. + +`getWebSockets` returns an `Array` which is the set of WebSockets attached to the Durable Object instance. An optional tag argument can be used to filter the list according to tags supplied when calling [`DurableObjectState::acceptWebSocket`](/durable-objects/api/state/#acceptwebsocket). + +:::note[`waitUntil` is not necessary] + +Disconnected WebSockets are not returned by this method, but `getWebSockets` may still return websockets even after `ws.close` has been called. For example, if the server-side WebSocket sends a close, but does not receive one back (and has not detected a disconnect from the client), then the connection is in the CLOSING “readyState”. The client might send more messages, so the WebSocket is technically not disconnected. + +::: + +#### Parameters + +- An optional tag of type `string`. + +#### Return values + +- An `Array` + +### `setWebSocketAutoResponse` + +`setWebSocketAutoResponse` is part of the [WebSocket Hibernation API](durable-objects/reference/websockets/#websocket-hibernation), which allows a Durable Object instance to be removed from memory to save costs while keeping its WebSockets connected. + +`setWebSocketAutoResponse` sets an automatic response, auto-response, for the request provided for all WebSockets attached to the Durable Object instance. If a request is received matching the provided request then the auto-response will be returned without waking WebSockets in hibernation and incurring billable duration charges. + +`setWebSocketAutoResponse` is a common alternative to setting up a server for static ping/pong messages because this can be handled without waking hibernating WebSockets. + +#### Parameters + +- An optional `WebSocketRequestResponsePair(request string, response string)` enabling any WebSocket accepted via [`DurableObjectState::acceptWebSocket`](/durable-objects/api/state/#acceptwebsocket) to automatically reply to the provided response when it receives the provided request. Both request and response are limited to 2,048 characters each. If the parameter is omitted any previously set auto-response configuration will be removed. [`DurableObjectState::getWebSocketAutoResponseTimestamp`](/durable-objects/api/state/#getwebsocketautoresponsetimestamp) will still reflect the last timestamp that an auto-response was sent. + +#### Return values + +- None. + +### `getWebSocketAutoResponse` + +`getWebSocketAutoResponse` returns the `WebSocketRequestResponsePair` object last set by [`DurableObjectState::setWebSocketAutoResponse`](/durable-objects/api/state/#setwebsocketautoresponse), or null if not auto-response has been set. + +:::note[inspect `WebSocketRequestResponsePair`] + +`WebSocketRequestResponsePair` can be inspected further by calling `getRequest` and `getResponse` methods. + +::: + +#### Parameters + +- None. + +#### Return values + +- A `WebSocketRequestResponsePair` or null + +### `getWebSocketAutoResponseTimestamp` + +`getWebSocketAutoResponseTimestamp` is part of the [WebSocket Hibernation API](durable-objects/reference/websockets/#websocket-hibernation), which allows a Durable Object instance to be removed from memory to save costs while keeping its WebSockets connected. + +`getWebSocketAutoResponseTimestamp` gets the most recent `Date` on which the given WebSocket sent an auto-response, or null if the given WebSocket never sent an auto-response. + +#### Parameters + +- A required `WebSocket`. + +#### Return values + +- A `Date` or null. + +### `setHibernatableWebSocketEventTimeout` + +`setHibernatableWebSocketEventTimeout` is part of the [WebSocket Hibernation API](durable-objects/reference/websockets/#websocket-hibernation), which allows a Durable Object instance to be removed from memory to save costs while keeping its WebSockets connected. + +`setHibernatableWebSocketEventTimeout` sets the maximum amount of time in milliseconds that a WebSocket event can run for. + +If no parameter or a parameter of `0` is provided and a timeout has been previously set, then the timeout will be unset. The maximum value of timeout is 604,800,000 ms (7 days). + +#### Parameters + +- An optional `number`. + +#### Return values + +- None. + +### `getHibernatableWebSocketEventTimeout` + +`getHibernatableWebSocketEventTimeout` is part of the [WebSocket Hibernation API](durable-objects/reference/websockets/#websocket-hibernation), which allows a Durable Object instance to be removed from memory to save costs while keeping its WebSockets connected. + +`getHibernatableWebSocketEventTimeout` gets the currently set hibernatable WebSocket event timeout if one has been set via [`DurableObjectState::setHibernatableWebSocketEventTimeout`](/durable-objects/api/state/#sethibernatablewebsocketeventtimeout). + +#### Parameters + +- None. + +#### Return values + +- A number or null if the timeout has not been set. + +### `getTags` + +`getTags` is part of the [WebSocket Hibernation API](durable-objects/reference/websockets/#websocket-hibernation), which allows a Durable Object instance to be removed from memory to save costs while keeping its WebSockets connected. + +`getTags` returns tags associated with a given WebSocket. This method throws an exception if the WebSocket has not been associated with the Durable Object instance via [`DurableObjectState::acceptWebSocket`](/durable-objects/api/state/#acceptwebsocket). + +#### Parameters + +- A required `WebSocket`. + +#### Return values + +- An `Array` of tags. + +### `abort` + +`abort` is used to forcibly reset a Durable Object instance. A JavaScript Error with the message passed as a parameter will be logged. This error is not able to be caught within the applciation code. + +```js +// Durable Object +export class MyDurableObject extends DurableObject { + constructor(ctx: DurableObjectState, env: Env) { + super(ctx, env); + } + + async sayHello() { + // Error: Hello, World! will be logged + this.ctx.abort("Hello, World!"); + } +} +``` + +:::caution[Not available in local development] + +`abort` is not available in local development with the `wrangler dev` CLI command. + +::: + +#### Parameters + +- An optional `string` . + +#### Return values + +- None. + +## Properties + +### `id` + +`id` is a readonly property of type `DurableObjectId` corresponding to the [`DurableObjectId`](/durable-objects/api/id) of the Durable Object instance. + +### `storage` + +`storage` is a readonly property of type `DurableObjectStorage` encapsulating the [Storage API](/durable-objects/api/storage-api). + +## Related resources + +- [Durable Objects: Easy, Fast, Correct – Choose Three](https://blog.cloudflare.com/durable-objects-easy-fast-correct-choose-three/). diff --git a/src/content/docs/durable-objects/api/websockets.mdx b/src/content/docs/durable-objects/api/websockets.mdx index cb9c2920f95ffac..d0da2752a58464f 100644 --- a/src/content/docs/durable-objects/api/websockets.mdx +++ b/src/content/docs/durable-objects/api/websockets.mdx @@ -3,7 +3,6 @@ title: WebSockets pcx_content_type: concept sidebar: order: 5 - --- import { Render, Type, MetaInfo } from "~/components"; @@ -28,7 +27,10 @@ To learn more about WebSocket Hibernation, refer to [Build a WebSocket server wi ### serializeAttachment -- serializeAttachment(value ): +- + serializeAttachment(value ) + + : - Keeps a copy of `value` in memory (not on disk) to survive hibernation. The value can be any type supported by the [structured clone algorithm](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm), which is true of most types. @@ -40,12 +42,15 @@ To learn more about WebSocket Hibernation, refer to [Build a WebSocket server wi - Retrieves the most recent value passed to `serializeAttachment()`, or `null` if none exists. - ## State Methods ### acceptWebSocket -- acceptWebSocket(ws , tags ): +- + acceptWebSocket(ws , tags{" "} + ) + + : - Adds a WebSocket to the set attached to this Durable Object. `ws.accept()` must not have been called separately. Once called, any incoming messages will be delivered by calling the Durable Object's `webSocketMessage()` handler, and `webSocketClose()` will be invoked upon disconnect. @@ -57,21 +62,36 @@ To learn more about WebSocket Hibernation, refer to [Build a WebSocket server wi ### getWebSockets -- getWebSockets(tag ): +- + getWebSockets(tag ) + + : - Gets an array of accepted WebSockets matching the given tag. Disconnected WebSockets 1 are automatically removed from the list. Calling `state.getWebSockets()` with no `tag` argument will return all WebSockets. - - 1 `state.getWebSockets()` may still return websockets even after `ws.close()` has been called. For example, if your server-side WebSocket (the Durable Object) sends a close, but does not receive one back (and has not detected a disconnect from the client), then the connection is in the `CLOSING` "readyState". The client might send more messages, so the WebSocket is technically not disconnected. + - 1 `state.getWebSockets()` may still return websockets even after + `ws.close()` has been called. For example, if your server-side WebSocket + (the Durable Object) sends a close, but does not receive one back (and has + not detected a disconnect from the client), then the connection is in the + `CLOSING` "readyState". The client might send more messages, so the + WebSocket is technically not disconnected. ### getTags -- getTags(ws ): +- + getTags(ws ) + + : - Returns an Array of tags associated with the given WebSocket. Throws an error if you have not called `state.acceptWebSocket()` on the given WebSocket. ### setWebSocketAutoResponse -- setWebSocketAutoResponse(webSocketRequestResponsePair ): +- + setWebSocketAutoResponse(webSocketRequestResponsePair{" "} + ) + + : - Sets an application level auto response that does not wake hibernated WebSockets. @@ -89,17 +109,24 @@ To learn more about WebSocket Hibernation, refer to [Build a WebSocket server wi - Gets the WebSocketRequestResponsePair(request , response ) currently set, or `null` if there is none. - - Each WebSocketRequestResponsePair(request , response ) Object provides methods for `getRequest()` and `getResponse()`. + - Each WebSocketRequestResponsePair(request , response ) Object provides methods for `getRequest()` and `getResponse()`. ### getWebSocketAutoResponseTimestamp -- getWebSocketAutoResponseTimestamp(ws ): +- + getWebSocketAutoResponseTimestamp(ws ) + + : - Gets the most recent `Date` when the WebSocket received an auto-response request, or `null` if the given WebSocket never received an auto-response request. ### setHibernatableWebSocketEventTimeout -- setHibernatableWebSocketEventTimeout(timeout ): +- + setHibernatableWebSocketEventTimeout(timeout {" "} + ) + + : - Sets the maximum amount of milliseconds a WebSocket event (refer to the handler methods below) can run for. @@ -113,12 +140,15 @@ To learn more about WebSocket Hibernation, refer to [Build a WebSocket server wi - Gets the currently set hibernatable WebSocket event timeout if any had been set with `state.setHibernatableWebSocketEventTimeout()`. - ## Handler Methods ### webSocketMessage -- webSocketMessage(ws , message ): +- + webSocketMessage(ws , message{" "} + ) + + : - Called by the system when an accepted WebSocket receives a message. @@ -128,7 +158,11 @@ To learn more about WebSocket Hibernation, refer to [Build a WebSocket server wi ### webSocketClose -- webSocketClose(ws , code , reason , wasClean ): +- + webSocketClose(ws , code , + reason , wasClean ) + + : - Called by the system when a WebSocket is closed. `wasClean()` is true if the connection closed cleanly, false otherwise. @@ -136,13 +170,15 @@ To learn more about WebSocket Hibernation, refer to [Build a WebSocket server wi ### webSocketError -- webSocketError(ws , error ) : +- + webSocketError(ws , error ) + : - Called by the system when any non-disconnection related errors occur. - This method can be `async`. -*** +--- ## Related resources diff --git a/src/content/docs/durable-objects/reference/in-memory-state.mdx b/src/content/docs/durable-objects/reference/in-memory-state.mdx index db2444861981ebe..d862330caa245b0 100644 --- a/src/content/docs/durable-objects/reference/in-memory-state.mdx +++ b/src/content/docs/durable-objects/reference/in-memory-state.mdx @@ -3,7 +3,6 @@ title: In-memory state in a Durable Object pcx_content_type: concept sidebar: order: 1 - --- In-memory state means that each Durable Object has one active instance at any particular time. All requests sent to that Durable Object are handled by that same instance. You can store some state in memory. @@ -14,21 +13,21 @@ A common pattern is to initialize a Durable Object from [persistent storage](/du ```js export class Counter { - constructor(state, env) { - this.state = state; - // `blockConcurrencyWhile()` ensures no requests are delivered until - // initialization completes. - this.state.blockConcurrencyWhile(async () => { - let stored = await this.state.storage.get("value"); - // After initialization, future reads do not need to access storage. - this.value = stored || 0; - }); - } - - // Handle HTTP requests from clients. - async fetch(request) { - // use this.value rather than storage - } + constructor(state, env) { + this.state = state; + // `blockConcurrencyWhile()` ensures no requests are delivered until + // initialization completes. + this.state.blockConcurrencyWhile(async () => { + let stored = await this.state.storage.get("value"); + // After initialization, future reads do not need to access storage. + this.value = stored || 0; + }); + } + + // Handle HTTP requests from clients. + async fetch(request) { + // use this.value rather than storage + } } ``` @@ -38,30 +37,8 @@ In the example above, using a global variable `value` instead of the instance va :::note[Built-in caching] - The Durable Object's storage has a built-in in-memory cache of its own. If you use `get()` to retrieve a value that was read or written recently, the result will be instantly returned from cache. Instead of writing initialization code like above, you could use `get("value")` whenever you need it, and rely on the built-in cache to make this fast. Refer to the [Build a counter example](/durable-objects/examples/build-a-counter/) to learn more about this approach. However, in applications with more complex state, explicitly storing state in your Object may be easier than making Storage API calls on every access. Depending on the configuration of your project, write your code in the way that is easiest for you. - ::: - -## `state.blockConcurrencyWhile()` method - -The `state.blockConcurrencyWhile()` method guarantees ordering, blocking concurrency within an object while the critical section is running. - -`state.blockConcurrencyWhile(callback)` has a return type of `Promise`, where `T` is the return type of `callback`. The method executes a callback (which may be `async`) while blocking any other events from being delivered to the object until the callback completes. - -This allows you to execute code that performs I/O (such as a `fetch()`) with the guarantee that the object's state will not unexpectedly change as a result of concurrent events. All events that were not explicitly initiated as part of the callback itself will be blocked. - -Events that will be blocked include new incoming requests and responses to outgoing requests (such as `fetch()`) that were initiated outside of the callback. Once the callback completes, these events will be delivered. - -`state.blockConcurrencyWhile()` is useful within the constructor of your object to perform initialization that must occur before any requests are delivered. This method may also be useful outside of the constructor. For example, if you want to run a sequence of storage operations and want to avoid concurrent actions changing the status of the storage, run your sequence of operations inside the `state.blockConcurrencyWhile()` callback. - -If the callback throws an exception, the object will be terminated and reset. This ensures that the object cannot be left stuck in an uninitialized state if something fails unexpectedly. To avoid this behavior, enclose the body of your callback in a `try...catch` block to ensure it cannot throw an exception. - -`state.blockConcurrencyWhile()` takes effect right away, pausing everything else, other than the currently executing event and any I/O started from within the `state.blockConcurrencyWhile()` callback. The value returned by the callback becomes the value returned by `state.blockConcurrencyWhile()` itself. - -To simulate eviction, use `state.blockConcurrencyWhile()`. Inside the callback, throw an exception. Throwing an exception causes the system to recreate the in-memory object, without affecting the durable storage. Uncaught exceptions inside the `state.blockConcurrencyWhile()` will break the object. - -To help prevent deadlocks in your critical section, there is a 30s timeout on the callback passed into `state.blockConcurrencyWhile`. When this timeout is exceeded, your Durable Object will be reset. It is generally good practice to have your critical section in `blockConcurrencyWhile()` be as brief as possible. diff --git a/src/content/docs/durable-objects/reference/websockets.mdx b/src/content/docs/durable-objects/reference/websockets.mdx index fc32364f937c402..514feabf96c2c45 100644 --- a/src/content/docs/durable-objects/reference/websockets.mdx +++ b/src/content/docs/durable-objects/reference/websockets.mdx @@ -3,7 +3,6 @@ pcx_content_type: concept title: Durable Objects with WebSockets sidebar: order: 3 - --- [WebSockets](/durable-objects/api/websockets/) allow real time communication between a client and server. Both Cloudflare Durable Objects and Workers can act as WebSocket endpoints – either as a client or as a server. @@ -20,10 +19,8 @@ Durable Objects can use the web standard APIs described in [WebSockets API](/dur :::caution[WebSockets disconnection] - Code updates will disconnect all WebSockets. If you deploy a new version of a Worker, every Durable Object is restarted. Any connections to old Durable Objects will be disconnected. - ::: ## WebSocket Hibernation @@ -32,19 +29,17 @@ The WebSocket Hibernation API allows a Durable Object that is not currently runn :::note - Hibernation is only supported when a Durable Object acts as a WebSocket server. Outgoing WebSockets cannot be hibernated as of now. - ::: -A Durable Object with WebSockets created via the Hibernation API will not incur billable [Duration (GB-s) charges](/durable-objects/platform/pricing/) during periods of inactivity, unlike Durable Objects using the [regular WebSockets API](/workers/runtime-apis/websockets/). +A Durable Object with WebSockets created via the Hibernation API will not incur billable [Duration (GB-s) charges](/durable-objects/platform/pricing/) during periods of inactivity, unlike Durable Objects using the [regular WebSockets API](/workers/runtime-apis/websockets/). Note that other events, for example [alarms](/durable-objects/api/alarms/), can prevent a Durable Object instance from being inactive and therefore prevent this cost savings. The WebSocket Hibernation API includes: -* Cloudflare-specific extensions to the web standard WebSocket API. -* Related methods on the [`state`](/durable-objects/api/websockets/#state-methods) of the Durable Object. -* [Handler methods](/durable-objects/api/websockets/#handler-methods) that a Durable Object can implement for processing WebSocket events. +- Cloudflare-specific extensions to the web standard WebSocket API. +- Related methods on the [`state`](/durable-objects/api/websockets/#state-methods) of the Durable Object. +- [Handler methods](/durable-objects/api/websockets/#handler-methods) that a Durable Object can implement for processing WebSocket events. The WebSocket Hibernation API enables you to terminate (not proxy) WebSocket connections within a Durable Object, and push messages to all connected clients based on state stored within the [Storage API](/durable-objects/api/storage-api/), HTTP fetches to external services, and/or data stored in [R2](/r2/) and [Workers KV](/kv/api/). @@ -54,16 +49,14 @@ If an event occurs for a hibernated Durable Object's corresponding handler metho :::caution[Support for local development] - Prior to `wrangler@3.13.2` and Miniflare `v3.20231016.0`, WebSockets did not hibernate when using local development environments such as `wrangler dev` or Miniflare. If you are using older versions, note that while hibernatable WebSocket events such as [`webSocketMessage()`](/durable-objects/api/websockets/#websocketmessage) will still be delivered, the Durable Object will never be evicted from memory. - ::: -*** +--- ## Related resources -* Refer to [Build a WebSocket server with WebSocket Hibernation](/durable-objects/examples/websocket-hibernation-server/) to learn more about building a WebSocket server using WebSocket Hibernation on Durable Objects and Workers. +- Refer to [Build a WebSocket server with WebSocket Hibernation](/durable-objects/examples/websocket-hibernation-server/) to learn more about building a WebSocket server using WebSocket Hibernation on Durable Objects and Workers. From 327660b61d32a0c92c5a4e8ec8badd71e809ca4c Mon Sep 17 00:00:00 2001 From: Jun Lee Date: Fri, 11 Oct 2024 10:11:41 +0100 Subject: [PATCH 02/10] Apply suggestions from code review Co-authored-by: hyperlint-ai[bot] <154288675+hyperlint-ai[bot]@users.noreply.github.com> Co-authored-by: Lambros Petrou --- src/content/docs/durable-objects/api/state.mdx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/content/docs/durable-objects/api/state.mdx b/src/content/docs/durable-objects/api/state.mdx index fbe197cece7eebb..d0686165626c7fc 100644 --- a/src/content/docs/durable-objects/api/state.mdx +++ b/src/content/docs/durable-objects/api/state.mdx @@ -11,7 +11,7 @@ import { Tabs, TabItem } from "~/components"; The `DurableObjectState` interface is accessible as an instance property on the Durable Objects class. This interface encapsulates methods that modify the state of a Durable Object, for example which WebSockets are attached to a Durable Object instance or how the runtime should handle concurrent Durable Object requests. -The `DurableObjectState` interface is different that the [Storage API](/durable-objects/api/storage-api) in that it does not have top level methods which manipulate persistant application data. These methods are instead encapsulated in the [`DurableObjectStorage`](/durable-objects/api/storage-api) interface and accessed by [`DurableObjectState::storage`](/durable-objects/api/state/#storage). +The `DurableObjectState` interface is different from the [Storage API](/durable-objects/api/storage-api) in that it does not have top-level methods which manipulate persistent application data. These methods are instead encapsulated in the [`DurableObjectStorage`](/durable-objects/api/storage-api) interface and accessed by [`DurableObjectState::storage`](/durable-objects/api/state/#storage). @@ -108,7 +108,7 @@ export class MyDurableObject extends DurableObject { `acceptWebSocket` is part of the [WebSocket Hibernation API](durable-objects/reference/websockets/#websocket-hibernation), which allows a Durable Object instance to be removed from memory to save costs while keeping its WebSockets connected. -`acceptWebSocket` adds a WebSocket to the set of WebSockets attached to the Durable Object instance. Once called, any incoming messages will be delivered by calling the Durable Object’s `webSocketMessage` handler, and `webSocketClose` will be invoked upon disconnect. After calling `acceptWebSocket`, the WebSocket is accepted and its `send` and `close` methods can be used. +`acceptWebSocket` adds a WebSocket to the set of WebSockets attached to the Durable Object instance. Once called, any incoming messages will be delivered by calling the Durable Object's `webSocketMessage` handler, and `webSocketClose` will be invoked upon disconnect. After calling `acceptWebSocket`, the WebSocket is accepted and its `send` and `close` methods can be used. The [WebSocket Hibernation API](durable-objects/reference/websockets/#websocket-hibernation) takes the place of the standard [WebSockets API](/workers/runtime-apis/websockets/). Therefore, `ws.accept` must not have been called separately and `ws.addEventListener` method will not receive events as they will instead be delivered to the Durable Object. @@ -131,7 +131,7 @@ The WebSocket Hibernation API permits a maximum of 32,768 WebSocket connections :::note[`waitUntil` is not necessary] -Disconnected WebSockets are not returned by this method, but `getWebSockets` may still return websockets even after `ws.close` has been called. For example, if the server-side WebSocket sends a close, but does not receive one back (and has not detected a disconnect from the client), then the connection is in the CLOSING “readyState”. The client might send more messages, so the WebSocket is technically not disconnected. +Disconnected WebSockets are not returned by this method, but `getWebSockets` may still return websockets even after `ws.close` has been called. For example, if the server-side WebSocket sends a close, but does not receive one back (and has not detected a disconnect from the client), then the connection is in the CLOSING 'readyState'. The client might send more messages, so the WebSocket is technically not disconnected. ::: @@ -237,7 +237,7 @@ If no parameter or a parameter of `0` is provided and a timeout has been previou ### `abort` -`abort` is used to forcibly reset a Durable Object instance. A JavaScript Error with the message passed as a parameter will be logged. This error is not able to be caught within the applciation code. +`abort` is used to forcibly reset a Durable Object instance. A JavaScript `Error` with the message passed as a parameter will be logged. This error is not able to be caught within the application code. ```js // Durable Object From 7fcda8740d38729776c164471a17d92d2b74a48a Mon Sep 17 00:00:00 2001 From: Jun Lee Date: Fri, 11 Oct 2024 11:06:46 +0100 Subject: [PATCH 03/10] PCX review. Adding glossary term for "event context", definition TBC. --- .../docs/durable-objects/api/state.mdx | 20 ++++++++-------- .../docs/durable-objects/api/websockets.mdx | 16 +++---------- src/content/glossary/durable-objects.yaml | 24 +++++++++++-------- 3 files changed, 27 insertions(+), 33 deletions(-) diff --git a/src/content/docs/durable-objects/api/state.mdx b/src/content/docs/durable-objects/api/state.mdx index d0686165626c7fc..f6fd9ea446bccd2 100644 --- a/src/content/docs/durable-objects/api/state.mdx +++ b/src/content/docs/durable-objects/api/state.mdx @@ -5,7 +5,7 @@ sidebar: order: 4 --- -import { Tabs, TabItem } from "~/components"; +import { Tabs, TabItem, GlossaryTooltip } from "~/components"; ## Description @@ -53,7 +53,7 @@ export class MyDurableObject extends DurableObject { ### `waitUntil` -`waitUntil` waits until the promise which is passed as a parameter resolves and can extends an event context up to 30 seconds after the last client disconnects. +`waitUntil` waits until the promise which is passed as a parameter resolves and can extends an event context up to 30 seconds after the last client disconnects. :::note[`waitUntil` is not necessary] @@ -71,13 +71,13 @@ The event context for a Durable Objects extends at least 60 seconds after the la ### `blockConcurrencyWhile` -`blockConcurrencyWhile` executes an async callback while blocking any other events from being delivered to the Durable Object instance until the callback completes. This method guarantees ordering and prevents concurrent requests. All events that were not explicitly initiated as part of the callback itself will be blocked. Once the callback completes, All other events will be delivered. +`blockConcurrencyWhile` executes an async callback while blocking any other events from being delivered to the Durable Object instance until the callback completes. This method guarantees ordering and prevents concurrent requests. All events that were not explicitly initiated as part of the callback itself will be blocked. Once the callback completes, all other events will be delivered. -`blockConcurrencyWhile` is commonly used within the constructor of the Durable Object class to enforce that initialization must occur before any requests are delivered. Another use case is executing `async` operations based on the current state of the Durable Object instance and using `blockConcurrencyWhile` to prevent that state from changing while yeilding the event loop. +`blockConcurrencyWhile` is commonly used within the constructor of the Durable Object class to enforce initialization to occur before any requests are delivered. Another use case is executing `async` operations based on the current state of the Durable Object instance and using `blockConcurrencyWhile` to prevent that state from changing while yielding the event loop. If the callback throws an exception, the object will be terminated and reset. This ensures that the object cannot be left stuck in an uninitialized state if something fails unexpectedly. To avoid this behavior, enclose the body of your callback in a `try...catch` block to ensure it cannot throw an exception. -To help mitigate deadlocks there is a 30s timeout applied when executing the callback. If this timeout is exceeded the Durable Object instance will be reset. It is best practice to have the callback do as little work as possible to improve overall request throughput to the Durable Object instance. +To help mitigate deadlocks there is a 30 second timeout applied when executing the callback. If this timeout is exceeded, the Durable Object instance will be reset. It is best practice to have the callback do as little work as possible to improve overall request throughput to the Durable Object instance. ```js // Durable Object @@ -131,7 +131,7 @@ The WebSocket Hibernation API permits a maximum of 32,768 WebSocket connections :::note[`waitUntil` is not necessary] -Disconnected WebSockets are not returned by this method, but `getWebSockets` may still return websockets even after `ws.close` has been called. For example, if the server-side WebSocket sends a close, but does not receive one back (and has not detected a disconnect from the client), then the connection is in the CLOSING 'readyState'. The client might send more messages, so the WebSocket is technically not disconnected. +Disconnected WebSockets are not returned by this method, but `getWebSockets` may still return WebSockets even after `ws.close` has been called. For example, if the server-side WebSocket sends a close, but does not receive one back (and has not detected a disconnect from the client), then the connection is in the CLOSING 'readyState'. The client might send more messages, so the WebSocket is technically not disconnected. ::: @@ -141,7 +141,7 @@ Disconnected WebSockets are not returned by this method, but `getWebSockets` may #### Return values -- An `Array` +- An `Array`. ### `setWebSocketAutoResponse` @@ -153,7 +153,7 @@ Disconnected WebSockets are not returned by this method, but `getWebSockets` may #### Parameters -- An optional `WebSocketRequestResponsePair(request string, response string)` enabling any WebSocket accepted via [`DurableObjectState::acceptWebSocket`](/durable-objects/api/state/#acceptwebsocket) to automatically reply to the provided response when it receives the provided request. Both request and response are limited to 2,048 characters each. If the parameter is omitted any previously set auto-response configuration will be removed. [`DurableObjectState::getWebSocketAutoResponseTimestamp`](/durable-objects/api/state/#getwebsocketautoresponsetimestamp) will still reflect the last timestamp that an auto-response was sent. +- An optional `WebSocketRequestResponsePair(request string, response string)` enabling any WebSocket accepted via [`DurableObjectState::acceptWebSocket`](/durable-objects/api/state/#acceptwebsocket) to automatically reply to the provided response when it receives the provided request. Both request and response are limited to 2,048 characters each. If the parameter is omitted, any previously set auto-response configuration will be removed. [`DurableObjectState::getWebSocketAutoResponseTimestamp`](/durable-objects/api/state/#getwebsocketautoresponsetimestamp) will still reflect the last timestamp that an auto-response was sent. #### Return values @@ -175,7 +175,7 @@ Disconnected WebSockets are not returned by this method, but `getWebSockets` may #### Return values -- A `WebSocketRequestResponsePair` or null +- A `WebSocketRequestResponsePair` or null. ### `getWebSocketAutoResponseTimestamp` @@ -219,7 +219,7 @@ If no parameter or a parameter of `0` is provided and a timeout has been previou #### Return values -- A number or null if the timeout has not been set. +- A number, or null if the timeout has not been set. ### `getTags` diff --git a/src/content/docs/durable-objects/api/websockets.mdx b/src/content/docs/durable-objects/api/websockets.mdx index d0da2752a58464f..05f65396d725a64 100644 --- a/src/content/docs/durable-objects/api/websockets.mdx +++ b/src/content/docs/durable-objects/api/websockets.mdx @@ -144,11 +144,7 @@ To learn more about WebSocket Hibernation, refer to [Build a WebSocket server wi ### webSocketMessage -- - webSocketMessage(ws , message{" "} - ) - - : +- webSocketMessage(ws , message{" "} ): - Called by the system when an accepted WebSocket receives a message. @@ -158,11 +154,7 @@ To learn more about WebSocket Hibernation, refer to [Build a WebSocket server wi ### webSocketClose -- - webSocketClose(ws , code , - reason , wasClean ) - - : +- webSocketClose(ws , code ,reason , wasClean ): - Called by the system when a WebSocket is closed. `wasClean()` is true if the connection closed cleanly, false otherwise. @@ -170,9 +162,7 @@ To learn more about WebSocket Hibernation, refer to [Build a WebSocket server wi ### webSocketError -- - webSocketError(ws , error ) - : +- webSocketError(ws , error ) : - Called by the system when any non-disconnection related errors occur. diff --git a/src/content/glossary/durable-objects.yaml b/src/content/glossary/durable-objects.yaml index 9e50d215c757821..237d7b38ce1dd5a 100644 --- a/src/content/glossary/durable-objects.yaml +++ b/src/content/glossary/durable-objects.yaml @@ -5,29 +5,29 @@ entries: general_definition: |- The product name, or the collective noun referring to more than one Durable Object instance. -- term: "Namespace" +- term: "namespace" general_definition: |- - A container for a collection of Durable Objects that all share the same Durable Object (class) definition. A single Namespace can have (tens of) millions of Durable Objects. Metrics are scoped per Namespace. + A container for a collection of Durable Objects that all share the same Durable Object (class) definition. A single namespace can have (tens of) millions of Durable Objects. Metrics are scoped per namespace. - term: "Durable Object" general_definition: |- - An individual Durable Object. A Durable Object is globally unique (referenced by ID), provides a global point of coordination for all methods/requests sent to it, and has private, persistent storage that is not shared with other Durable Objects within a Namespace. + An individual instance of a Durable Object class. A Durable Object is globally unique (referenced by ID), provides a global point of coordination for all methods/requests sent to it, and has private, persistent storage that is not shared with other Durable Objects within a namespace. -- term: "Stub" +- term: "stub" general_definition: |- - An object that refers to a unique Durable Object within a Namespace and allows you to call into that Durable Object via RPC methods or the `fetch` API. For example, `let stub = env.MY_DURABLE_OBJECT.get(id)` + An object that refers to a unique Durable Object within a namespace and allows you to call into that Durable Object via RPC methods or the `fetch` API. For example, `let stub = env.MY_DURABLE_OBJECT.get(id)` - term: "actor" general_definition: |- - A term referring to a unique Durable Object. + A term referring to a unique Durable Object. See "Durable Object". - term: "instance" general_definition: |- - See 'actor'. + See "actor". - term: "Durable Object class" general_definition: |- - The JavaScript class that defines the methods (RPC) and handlers (`fetch`, `alarm`) as part of your Durable Object, and/or an optional `constructor`. All Durable Objects within a single Namespace share the same class definition. + The JavaScript class that defines the methods (RPC) and handlers (`fetch`, `alarm`) as part of your Durable Object, and/or an optional `constructor`. All Durable Objects within a single namespace share the same class definition. - term: "Storage Backend" general_definition: |- @@ -50,7 +50,7 @@ entries: general_definition: |- API methods part of Storage API that support SQL querying. -- term: Migration +- term: "migration" general_definition: |- A Durable Object migration is a mapping process from a class name to a runtime state. Initiate a Durable Object migration when you need to: @@ -60,6 +60,10 @@ entries: - Delete a Durable Object class. - Transfer an existing Durable Objects class. -- term: Alarm +- term: "alarm" general_definition: |- A Durable Object alarm is a mechanism that allows you to schedule the Durable Object to be woken up at a time in the future. + +- term: "event context" + general_definition: |- + The duration for which a Durable Object is kept in memory. \ No newline at end of file From 8ec76f8c5f200e4102fc325849db077ef08c3c49 Mon Sep 17 00:00:00 2001 From: Jun Lee Date: Fri, 11 Oct 2024 11:23:44 +0100 Subject: [PATCH 04/10] Adding missing / from some links. --- src/content/docs/durable-objects/api/state.mdx | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/content/docs/durable-objects/api/state.mdx b/src/content/docs/durable-objects/api/state.mdx index f6fd9ea446bccd2..fae4e1cdee4a1bb 100644 --- a/src/content/docs/durable-objects/api/state.mdx +++ b/src/content/docs/durable-objects/api/state.mdx @@ -106,11 +106,11 @@ export class MyDurableObject extends DurableObject { ### `acceptWebSocket` -`acceptWebSocket` is part of the [WebSocket Hibernation API](durable-objects/reference/websockets/#websocket-hibernation), which allows a Durable Object instance to be removed from memory to save costs while keeping its WebSockets connected. +`acceptWebSocket` is part of the [WebSocket Hibernation API](/durable-objects/reference/websockets/#websocket-hibernation), which allows a Durable Object instance to be removed from memory to save costs while keeping its WebSockets connected. `acceptWebSocket` adds a WebSocket to the set of WebSockets attached to the Durable Object instance. Once called, any incoming messages will be delivered by calling the Durable Object's `webSocketMessage` handler, and `webSocketClose` will be invoked upon disconnect. After calling `acceptWebSocket`, the WebSocket is accepted and its `send` and `close` methods can be used. -The [WebSocket Hibernation API](durable-objects/reference/websockets/#websocket-hibernation) takes the place of the standard [WebSockets API](/workers/runtime-apis/websockets/). Therefore, `ws.accept` must not have been called separately and `ws.addEventListener` method will not receive events as they will instead be delivered to the Durable Object. +The [WebSocket Hibernation API](/durable-objects/reference/websockets/#websocket-hibernation) takes the place of the standard [WebSockets API](/workers/runtime-apis/websockets/). Therefore, `ws.accept` must not have been called separately and `ws.addEventListener` method will not receive events as they will instead be delivered to the Durable Object. The WebSocket Hibernation API permits a maximum of 32,768 WebSocket connections per Durable Object instance, but the CPU and memory usage of a given workload may further limit the practical number of simultaneous connections. @@ -125,7 +125,7 @@ The WebSocket Hibernation API permits a maximum of 32,768 WebSocket connections ### `getWebSockets` -`getWebSockets` is part of the [WebSocket Hibernation API](durable-objects/reference/websockets/#websocket-hibernation), which allows a Durable Object instance to be removed from memory to save costs while keeping its WebSockets connected. +`getWebSockets` is part of the [WebSocket Hibernation API](/durable-objects/reference/websockets/#websocket-hibernation), which allows a Durable Object instance to be removed from memory to save costs while keeping its WebSockets connected. `getWebSockets` returns an `Array` which is the set of WebSockets attached to the Durable Object instance. An optional tag argument can be used to filter the list according to tags supplied when calling [`DurableObjectState::acceptWebSocket`](/durable-objects/api/state/#acceptwebsocket). @@ -145,7 +145,7 @@ Disconnected WebSockets are not returned by this method, but `getWebSockets` may ### `setWebSocketAutoResponse` -`setWebSocketAutoResponse` is part of the [WebSocket Hibernation API](durable-objects/reference/websockets/#websocket-hibernation), which allows a Durable Object instance to be removed from memory to save costs while keeping its WebSockets connected. +`setWebSocketAutoResponse` is part of the [WebSocket Hibernation API](/durable-objects/reference/websockets/#websocket-hibernation), which allows a Durable Object instance to be removed from memory to save costs while keeping its WebSockets connected. `setWebSocketAutoResponse` sets an automatic response, auto-response, for the request provided for all WebSockets attached to the Durable Object instance. If a request is received matching the provided request then the auto-response will be returned without waking WebSockets in hibernation and incurring billable duration charges. @@ -179,7 +179,7 @@ Disconnected WebSockets are not returned by this method, but `getWebSockets` may ### `getWebSocketAutoResponseTimestamp` -`getWebSocketAutoResponseTimestamp` is part of the [WebSocket Hibernation API](durable-objects/reference/websockets/#websocket-hibernation), which allows a Durable Object instance to be removed from memory to save costs while keeping its WebSockets connected. +`getWebSocketAutoResponseTimestamp` is part of the [WebSocket Hibernation API](/durable-objects/reference/websockets/#websocket-hibernation), which allows a Durable Object instance to be removed from memory to save costs while keeping its WebSockets connected. `getWebSocketAutoResponseTimestamp` gets the most recent `Date` on which the given WebSocket sent an auto-response, or null if the given WebSocket never sent an auto-response. @@ -193,7 +193,7 @@ Disconnected WebSockets are not returned by this method, but `getWebSockets` may ### `setHibernatableWebSocketEventTimeout` -`setHibernatableWebSocketEventTimeout` is part of the [WebSocket Hibernation API](durable-objects/reference/websockets/#websocket-hibernation), which allows a Durable Object instance to be removed from memory to save costs while keeping its WebSockets connected. +`setHibernatableWebSocketEventTimeout` is part of the [WebSocket Hibernation API](/durable-objects/reference/websockets/#websocket-hibernation), which allows a Durable Object instance to be removed from memory to save costs while keeping its WebSockets connected. `setHibernatableWebSocketEventTimeout` sets the maximum amount of time in milliseconds that a WebSocket event can run for. @@ -209,7 +209,7 @@ If no parameter or a parameter of `0` is provided and a timeout has been previou ### `getHibernatableWebSocketEventTimeout` -`getHibernatableWebSocketEventTimeout` is part of the [WebSocket Hibernation API](durable-objects/reference/websockets/#websocket-hibernation), which allows a Durable Object instance to be removed from memory to save costs while keeping its WebSockets connected. +`getHibernatableWebSocketEventTimeout` is part of the [WebSocket Hibernation API](/durable-objects/reference/websockets/#websocket-hibernation), which allows a Durable Object instance to be removed from memory to save costs while keeping its WebSockets connected. `getHibernatableWebSocketEventTimeout` gets the currently set hibernatable WebSocket event timeout if one has been set via [`DurableObjectState::setHibernatableWebSocketEventTimeout`](/durable-objects/api/state/#sethibernatablewebsocketeventtimeout). @@ -223,7 +223,7 @@ If no parameter or a parameter of `0` is provided and a timeout has been previou ### `getTags` -`getTags` is part of the [WebSocket Hibernation API](durable-objects/reference/websockets/#websocket-hibernation), which allows a Durable Object instance to be removed from memory to save costs while keeping its WebSockets connected. +`getTags` is part of the [WebSocket Hibernation API](/durable-objects/reference/websockets/#websocket-hibernation), which allows a Durable Object instance to be removed from memory to save costs while keeping its WebSockets connected. `getTags` returns tags associated with a given WebSocket. This method throws an exception if the WebSocket has not been associated with the Durable Object instance via [`DurableObjectState::acceptWebSocket`](/durable-objects/api/state/#acceptwebsocket). From c4201c8a7d07199b63aada59d2eb9f95f585a54b Mon Sep 17 00:00:00 2001 From: Jun Lee Date: Fri, 11 Oct 2024 15:30:17 +0100 Subject: [PATCH 05/10] Adding in proper definition for "event context" in the glossary. --- src/content/glossary/durable-objects.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/glossary/durable-objects.yaml b/src/content/glossary/durable-objects.yaml index 237d7b38ce1dd5a..a35a04ca5651c63 100644 --- a/src/content/glossary/durable-objects.yaml +++ b/src/content/glossary/durable-objects.yaml @@ -66,4 +66,4 @@ entries: - term: "event context" general_definition: |- - The duration for which a Durable Object is kept in memory. \ No newline at end of file + The duration of time that a Durable Object instance is processing an event, such as a remote procedure call. Compute duration charges are incurred for the duration of the event context. \ No newline at end of file From 6047f2561166be22c87fc5f8d4333efadeb8b55e Mon Sep 17 00:00:00 2001 From: Jun Lee Date: Fri, 11 Oct 2024 15:42:13 +0100 Subject: [PATCH 06/10] Cleaning up "Durable Object instance" to "Durable Object", to align with glossary definition. --- src/content/changelogs/workers.yaml | 2 +- .../docs/durable-objects/api/alarms.mdx | 2 +- src/content/docs/durable-objects/api/id.mdx | 6 ++-- .../docs/durable-objects/api/namespace.mdx | 14 ++++---- .../docs/durable-objects/api/state.mdx | 36 +++++++++---------- .../docs/durable-objects/api/storage-api.mdx | 2 +- src/content/docs/durable-objects/api/stub.mdx | 6 ++-- .../docs/durable-objects/api/websockets.mdx | 2 +- .../examples/build-a-rate-limiter.mdx | 2 +- .../examples/websocket-hibernation-server.mdx | 8 ++--- .../examples/websocket-server.mdx | 4 +-- .../get-started/tutorial-with-sql-api.mdx | 6 ++-- .../get-started/walkthrough.mdx | 2 +- .../durable-objects/platform/known-issues.mdx | 2 +- .../reference/data-location.mdx | 4 +-- .../reference/durable-objects-migrations.mdx | 2 +- .../durable-objects/reference/websockets.mdx | 2 +- .../gradual-deployments.mdx | 2 +- .../changelog/historical-changelog.mdx | 2 +- src/content/docs/workers/testing/index.mdx | 2 +- .../get-started/migrate-from-miniflare-2.mdx | 2 +- .../testing/vitest-integration/test-apis.mdx | 4 +-- src/content/glossary/durable-objects.yaml | 6 ++-- 23 files changed, 60 insertions(+), 60 deletions(-) diff --git a/src/content/changelogs/workers.yaml b/src/content/changelogs/workers.yaml index 28553684135e887..8dc101fc404d1b3 100644 --- a/src/content/changelogs/workers.yaml +++ b/src/content/changelogs/workers.yaml @@ -206,7 +206,7 @@ entries: - publish_date: "2023-05-05" description: |- - The new `nodeJsCompatModule` type can be used with a Worker bundle to emulate a Node.js environment. Common Node.js globals such as `process` and `Buffer` will be present, and `require('...')` can be used to load Node.js built-ins without the `node:` specifier prefix. - - Fixed an issue where websocket connections would be disconnected when updating workers. Now, only websockets connected to Durable Object instances are disconnected by updates to that Durable Object’s code. + - Fixed an issue where websocket connections would be disconnected when updating workers. Now, only WebSockets connected to Durable Objects are disconnected by updates to that Durable Object’s code. - publish_date: "2023-04-28" description: |- - The Web Crypto API now supports curves Ed25519 and X25519 defined in the Secure Curves specification. diff --git a/src/content/docs/durable-objects/api/alarms.mdx b/src/content/docs/durable-objects/api/alarms.mdx index b9e3c079209c34d..db3a94f565ec928 100644 --- a/src/content/docs/durable-objects/api/alarms.mdx +++ b/src/content/docs/durable-objects/api/alarms.mdx @@ -13,7 +13,7 @@ Durable Objects alarms allow you to schedule the Durable Object to be woken up a Notably: -- Each Durable Object instance is able to schedule a single alarm at a time by calling `setAlarm()`. +- Each Durable Object is able to schedule a single alarm at a time by calling `setAlarm()`. - Alarms have guaranteed at-least-once execution and are retried automatically when the `alarm()` handler throws. - Retries are performed using exponential backoff starting at a 2 second delay from the first failure with up to 6 retries allowed. diff --git a/src/content/docs/durable-objects/api/id.mdx b/src/content/docs/durable-objects/api/id.mdx index 97c339ff62fa022..29d492aa7f69a26 100644 --- a/src/content/docs/durable-objects/api/id.mdx +++ b/src/content/docs/durable-objects/api/id.mdx @@ -9,13 +9,13 @@ import { Tabs, TabItem } from "~/components"; ## Description -The `DurableObjectId` interface refers to a new or existing Durable Object instance. This interface is most frequently used by [`DurableObjectNamespace::get`](/durable-objects/api/namespace/#get) to obtain a stub for submitting requests to a Durable Object instance. +The `DurableObjectId` interface refers to a new or existing Durable Object. This interface is most frequently used by [`DurableObjectNamespace::get`](/durable-objects/api/namespace/#get) to obtain a stub for submitting requests to a Durable Object. -Note that creating an ID for a Durable Object instance does not create the Durable Object. The Durable Object is created lazily after calling [`DurableObjectNamespace::get`](/durable-objects/api/namespace/#get) to create a [`DurableObjectStub`](/durable-objects/api/stub) from a `DurableObjectId`. This ensures that objects are not constructed until they are actually accessed. +Note that creating an ID for a Durable Object does not create the Durable Object. The Durable Object is created lazily after calling [`DurableObjectNamespace::get`](/durable-objects/api/namespace/#get) to create a [`DurableObjectStub`](/durable-objects/api/stub) from a `DurableObjectId`. This ensures that objects are not constructed until they are actually accessed. :::note[`DurableObjectId`] -If you are experiencing an issue with a particular Durable Object instance, you may wish to log the `DurableObjectId` from your Worker and include it in your Cloudflare support request. +If you are experiencing an issue with a particular Durable Object, you may wish to log the `DurableObjectId` from your Worker and include it in your Cloudflare support request. ::: diff --git a/src/content/docs/durable-objects/api/namespace.mdx b/src/content/docs/durable-objects/api/namespace.mdx index 4e53d3398dc9131..aef707d2eac81b4 100644 --- a/src/content/docs/durable-objects/api/namespace.mdx +++ b/src/content/docs/durable-objects/api/namespace.mdx @@ -9,9 +9,9 @@ import { Tabs, TabItem } from "~/components"; ## Description -The `DurableObjectNamespace` interface is used to obtain a reference to a new or existing Durable Object instance. The interface is accessible from the fetch handler on a Cloudflare Worker via the `env` parameter, which is the standard interface when referencing bindings declared in `wrangler.toml`. +The `DurableObjectNamespace` interface is used to obtain a reference to a new or existing Durable Object. The interface is accessible from the fetch handler on a Cloudflare Worker via the `env` parameter, which is the standard interface when referencing bindings declared in `wrangler.toml`. -This interface defines several [methods](/durable-objects/api/namespace/#methods) that can be used to create an ID for a Durable Object instance. Note that creating an ID for a Durable Object instance does not create the Durable Object. The Durable Object is created lazily after calling [`DurableObjectNamespace::get`](/durable-objects/api/namespace/#get) to create a [`DurableObjectStub`](/durable-objects/api/stub) from a `DurableObjectId`. This ensures that objects are not constructed until they are actually accessed. +This interface defines several [methods](/durable-objects/api/namespace/#methods) that can be used to create an ID for a Durable Object. Note that creating an ID for a Durable Object does not create the Durable Object. The Durable Object is created lazily after calling [`DurableObjectNamespace::get`](/durable-objects/api/namespace/#get) to create a [`DurableObjectStub`](/durable-objects/api/stub) from a `DurableObjectId`. This ensures that objects are not constructed until they are actually accessed. @@ -29,7 +29,7 @@ export default { // Every unique ID refers to an individual instance of the Durable Object class const id = env.MY_DURABLE_OBJECT.idFromName("foo"); - // A stub is a client Object used to invoke methods defined by the Durable Object instance + // A stub is a client Object used to invoke methods defined by the Durable Object const stub = env.MY_DURABLE_OBJECT.get(id); ... } @@ -56,7 +56,7 @@ export default { // Every unique ID refers to an individual instance of the Durable Object class const id = env.MY_DURABLE_OBJECT.idFromName("foo"); - // A stub is a client Object used to invoke methods defined by the Durable Object instance + // A stub is a client Object used to invoke methods defined by the Durable Object const stub = env.MY_DURABLE_OBJECT.get(id); ... } @@ -78,7 +78,7 @@ const barId = env.MY_DURABLE_OBJECT.idFromName("bar"); #### Parameters -- A required string to be used to generate a [`DurableObjectId`](/durable-objects/api/id) corresponding to the name of a Durable Object instance. +- A required string to be used to generate a [`DurableObjectId`](/durable-objects/api/id) corresponding to the name of a Durable Object. #### Return values @@ -130,7 +130,7 @@ const id = env.MY_DURABLE_OBJECT.idFromString(session_id); ### `get` -`get` obtains a [`DurableObjectStub`](/durable-objects/api/stub) from a [`DurableObjectId`](/durable-objects/api/id) which can be used to invoke methods on a Durable Object instance. +`get` obtains a [`DurableObjectStub`](/durable-objects/api/stub) from a [`DurableObjectId`](/durable-objects/api/id) which can be used to invoke methods on a Durable Object. ```js const id = env.MY_DURABLE_OBJECT.newUniqueId(); @@ -147,7 +147,7 @@ const stub = env.MY_DURABLE_OBJECT.get(id); ### `jurisdiction` -`jurisdiction` creates a subnamespace from a namespace where all Durable Object instance IDs and references created from that subnamespace will be restricted to the specified [jurisdiction](/durable-objects/reference/data-location/#restrict-durable-objects-to-a-jurisdiction). +`jurisdiction` creates a subnamespace from a namespace where all Durable Object IDs and references created from that subnamespace will be restricted to the specified [jurisdiction](/durable-objects/reference/data-location/#restrict-durable-objects-to-a-jurisdiction). ```js const subnamespace = env.MY_DURABLE_OBJECT.jurisdiction("foo"); diff --git a/src/content/docs/durable-objects/api/state.mdx b/src/content/docs/durable-objects/api/state.mdx index fae4e1cdee4a1bb..568bed9da99e2cb 100644 --- a/src/content/docs/durable-objects/api/state.mdx +++ b/src/content/docs/durable-objects/api/state.mdx @@ -9,7 +9,7 @@ import { Tabs, TabItem, GlossaryTooltip } from "~/components"; ## Description -The `DurableObjectState` interface is accessible as an instance property on the Durable Objects class. This interface encapsulates methods that modify the state of a Durable Object, for example which WebSockets are attached to a Durable Object instance or how the runtime should handle concurrent Durable Object requests. +The `DurableObjectState` interface is accessible as an instance property on the Durable Objects class. This interface encapsulates methods that modify the state of a Durable Object, for example which WebSockets are attached to a Durable Object or how the runtime should handle concurrent Durable Object requests. The `DurableObjectState` interface is different from the [Storage API](/durable-objects/api/storage-api) in that it does not have top-level methods which manipulate persistent application data. These methods are instead encapsulated in the [`DurableObjectStorage`](/durable-objects/api/storage-api) interface and accessed by [`DurableObjectState::storage`](/durable-objects/api/state/#storage). @@ -71,13 +71,13 @@ The event context for a Durable Objects extends at least 60 seconds after the la ### `blockConcurrencyWhile` -`blockConcurrencyWhile` executes an async callback while blocking any other events from being delivered to the Durable Object instance until the callback completes. This method guarantees ordering and prevents concurrent requests. All events that were not explicitly initiated as part of the callback itself will be blocked. Once the callback completes, all other events will be delivered. +`blockConcurrencyWhile` executes an async callback while blocking any other events from being delivered to the Durable Object until the callback completes. This method guarantees ordering and prevents concurrent requests. All events that were not explicitly initiated as part of the callback itself will be blocked. Once the callback completes, all other events will be delivered. -`blockConcurrencyWhile` is commonly used within the constructor of the Durable Object class to enforce initialization to occur before any requests are delivered. Another use case is executing `async` operations based on the current state of the Durable Object instance and using `blockConcurrencyWhile` to prevent that state from changing while yielding the event loop. +`blockConcurrencyWhile` is commonly used within the constructor of the Durable Object class to enforce initialization to occur before any requests are delivered. Another use case is executing `async` operations based on the current state of the Durable Object and using `blockConcurrencyWhile` to prevent that state from changing while yielding the event loop. If the callback throws an exception, the object will be terminated and reset. This ensures that the object cannot be left stuck in an uninitialized state if something fails unexpectedly. To avoid this behavior, enclose the body of your callback in a `try...catch` block to ensure it cannot throw an exception. -To help mitigate deadlocks there is a 30 second timeout applied when executing the callback. If this timeout is exceeded, the Durable Object instance will be reset. It is best practice to have the callback do as little work as possible to improve overall request throughput to the Durable Object instance. +To help mitigate deadlocks there is a 30 second timeout applied when executing the callback. If this timeout is exceeded, the Durable Object will be reset. It is best practice to have the callback do as little work as possible to improve overall request throughput to the Durable Object. ```js // Durable Object @@ -106,13 +106,13 @@ export class MyDurableObject extends DurableObject { ### `acceptWebSocket` -`acceptWebSocket` is part of the [WebSocket Hibernation API](/durable-objects/reference/websockets/#websocket-hibernation), which allows a Durable Object instance to be removed from memory to save costs while keeping its WebSockets connected. +`acceptWebSocket` is part of the [WebSocket Hibernation API](/durable-objects/reference/websockets/#websocket-hibernation), which allows a Durable Object to be removed from memory to save costs while keeping its WebSockets connected. -`acceptWebSocket` adds a WebSocket to the set of WebSockets attached to the Durable Object instance. Once called, any incoming messages will be delivered by calling the Durable Object's `webSocketMessage` handler, and `webSocketClose` will be invoked upon disconnect. After calling `acceptWebSocket`, the WebSocket is accepted and its `send` and `close` methods can be used. +`acceptWebSocket` adds a WebSocket to the set of WebSockets attached to the Durable Object. Once called, any incoming messages will be delivered by calling the Durable Object's `webSocketMessage` handler, and `webSocketClose` will be invoked upon disconnect. After calling `acceptWebSocket`, the WebSocket is accepted and its `send` and `close` methods can be used. The [WebSocket Hibernation API](/durable-objects/reference/websockets/#websocket-hibernation) takes the place of the standard [WebSockets API](/workers/runtime-apis/websockets/). Therefore, `ws.accept` must not have been called separately and `ws.addEventListener` method will not receive events as they will instead be delivered to the Durable Object. -The WebSocket Hibernation API permits a maximum of 32,768 WebSocket connections per Durable Object instance, but the CPU and memory usage of a given workload may further limit the practical number of simultaneous connections. +The WebSocket Hibernation API permits a maximum of 32,768 WebSocket connections per Durable Object, but the CPU and memory usage of a given workload may further limit the practical number of simultaneous connections. #### Parameters @@ -125,9 +125,9 @@ The WebSocket Hibernation API permits a maximum of 32,768 WebSocket connections ### `getWebSockets` -`getWebSockets` is part of the [WebSocket Hibernation API](/durable-objects/reference/websockets/#websocket-hibernation), which allows a Durable Object instance to be removed from memory to save costs while keeping its WebSockets connected. +`getWebSockets` is part of the [WebSocket Hibernation API](/durable-objects/reference/websockets/#websocket-hibernation), which allows a Durable Object to be removed from memory to save costs while keeping its WebSockets connected. -`getWebSockets` returns an `Array` which is the set of WebSockets attached to the Durable Object instance. An optional tag argument can be used to filter the list according to tags supplied when calling [`DurableObjectState::acceptWebSocket`](/durable-objects/api/state/#acceptwebsocket). +`getWebSockets` returns an `Array` which is the set of WebSockets attached to the Durable Object. An optional tag argument can be used to filter the list according to tags supplied when calling [`DurableObjectState::acceptWebSocket`](/durable-objects/api/state/#acceptwebsocket). :::note[`waitUntil` is not necessary] @@ -145,9 +145,9 @@ Disconnected WebSockets are not returned by this method, but `getWebSockets` may ### `setWebSocketAutoResponse` -`setWebSocketAutoResponse` is part of the [WebSocket Hibernation API](/durable-objects/reference/websockets/#websocket-hibernation), which allows a Durable Object instance to be removed from memory to save costs while keeping its WebSockets connected. +`setWebSocketAutoResponse` is part of the [WebSocket Hibernation API](/durable-objects/reference/websockets/#websocket-hibernation), which allows a Durable Object to be removed from memory to save costs while keeping its WebSockets connected. -`setWebSocketAutoResponse` sets an automatic response, auto-response, for the request provided for all WebSockets attached to the Durable Object instance. If a request is received matching the provided request then the auto-response will be returned without waking WebSockets in hibernation and incurring billable duration charges. +`setWebSocketAutoResponse` sets an automatic response, auto-response, for the request provided for all WebSockets attached to the Durable Object. If a request is received matching the provided request then the auto-response will be returned without waking WebSockets in hibernation and incurring billable duration charges. `setWebSocketAutoResponse` is a common alternative to setting up a server for static ping/pong messages because this can be handled without waking hibernating WebSockets. @@ -179,7 +179,7 @@ Disconnected WebSockets are not returned by this method, but `getWebSockets` may ### `getWebSocketAutoResponseTimestamp` -`getWebSocketAutoResponseTimestamp` is part of the [WebSocket Hibernation API](/durable-objects/reference/websockets/#websocket-hibernation), which allows a Durable Object instance to be removed from memory to save costs while keeping its WebSockets connected. +`getWebSocketAutoResponseTimestamp` is part of the [WebSocket Hibernation API](/durable-objects/reference/websockets/#websocket-hibernation), which allows a Durable Object to be removed from memory to save costs while keeping its WebSockets connected. `getWebSocketAutoResponseTimestamp` gets the most recent `Date` on which the given WebSocket sent an auto-response, or null if the given WebSocket never sent an auto-response. @@ -193,7 +193,7 @@ Disconnected WebSockets are not returned by this method, but `getWebSockets` may ### `setHibernatableWebSocketEventTimeout` -`setHibernatableWebSocketEventTimeout` is part of the [WebSocket Hibernation API](/durable-objects/reference/websockets/#websocket-hibernation), which allows a Durable Object instance to be removed from memory to save costs while keeping its WebSockets connected. +`setHibernatableWebSocketEventTimeout` is part of the [WebSocket Hibernation API](/durable-objects/reference/websockets/#websocket-hibernation), which allows a Durable Object to be removed from memory to save costs while keeping its WebSockets connected. `setHibernatableWebSocketEventTimeout` sets the maximum amount of time in milliseconds that a WebSocket event can run for. @@ -209,7 +209,7 @@ If no parameter or a parameter of `0` is provided and a timeout has been previou ### `getHibernatableWebSocketEventTimeout` -`getHibernatableWebSocketEventTimeout` is part of the [WebSocket Hibernation API](/durable-objects/reference/websockets/#websocket-hibernation), which allows a Durable Object instance to be removed from memory to save costs while keeping its WebSockets connected. +`getHibernatableWebSocketEventTimeout` is part of the [WebSocket Hibernation API](/durable-objects/reference/websockets/#websocket-hibernation), which allows a Durable Object to be removed from memory to save costs while keeping its WebSockets connected. `getHibernatableWebSocketEventTimeout` gets the currently set hibernatable WebSocket event timeout if one has been set via [`DurableObjectState::setHibernatableWebSocketEventTimeout`](/durable-objects/api/state/#sethibernatablewebsocketeventtimeout). @@ -223,9 +223,9 @@ If no parameter or a parameter of `0` is provided and a timeout has been previou ### `getTags` -`getTags` is part of the [WebSocket Hibernation API](/durable-objects/reference/websockets/#websocket-hibernation), which allows a Durable Object instance to be removed from memory to save costs while keeping its WebSockets connected. +`getTags` is part of the [WebSocket Hibernation API](/durable-objects/reference/websockets/#websocket-hibernation), which allows a Durable Object to be removed from memory to save costs while keeping its WebSockets connected. -`getTags` returns tags associated with a given WebSocket. This method throws an exception if the WebSocket has not been associated with the Durable Object instance via [`DurableObjectState::acceptWebSocket`](/durable-objects/api/state/#acceptwebsocket). +`getTags` returns tags associated with a given WebSocket. This method throws an exception if the WebSocket has not been associated with the Durable Object via [`DurableObjectState::acceptWebSocket`](/durable-objects/api/state/#acceptwebsocket). #### Parameters @@ -237,7 +237,7 @@ If no parameter or a parameter of `0` is provided and a timeout has been previou ### `abort` -`abort` is used to forcibly reset a Durable Object instance. A JavaScript `Error` with the message passed as a parameter will be logged. This error is not able to be caught within the application code. +`abort` is used to forcibly reset a Durable Object. A JavaScript `Error` with the message passed as a parameter will be logged. This error is not able to be caught within the application code. ```js // Durable Object @@ -271,7 +271,7 @@ export class MyDurableObject extends DurableObject { ### `id` -`id` is a readonly property of type `DurableObjectId` corresponding to the [`DurableObjectId`](/durable-objects/api/id) of the Durable Object instance. +`id` is a readonly property of type `DurableObjectId` corresponding to the [`DurableObjectId`](/durable-objects/api/id) of the Durable Object. ### `storage` diff --git a/src/content/docs/durable-objects/api/storage-api.mdx b/src/content/docs/durable-objects/api/storage-api.mdx index 32042566cc648a2..c87773f37d091c1 100644 --- a/src/content/docs/durable-objects/api/storage-api.mdx +++ b/src/content/docs/durable-objects/api/storage-api.mdx @@ -12,7 +12,7 @@ The Storage API allows Durable Objects to access transactional and strongly cons Durable Objects gain access to a persistent Storage API via `ctx.storage`, on the `ctx` parameter passed to the Durable Object constructor. -While access to a Durable Object instance is single-threaded, request executions can still interleave with each other when they wait on I/O, such as when waiting on the promises returned by persistent storage methods or `fetch()` requests. +While access to a Durable Object is single-threaded, request executions can still interleave with each other when they wait on I/O, such as when waiting on the promises returned by persistent storage methods or `fetch()` requests. The following code snippet shows you how to store and retrieve data using the Storage API. diff --git a/src/content/docs/durable-objects/api/stub.mdx b/src/content/docs/durable-objects/api/stub.mdx index 19dfbd9cc724082..68e78a54d821ae8 100644 --- a/src/content/docs/durable-objects/api/stub.mdx +++ b/src/content/docs/durable-objects/api/stub.mdx @@ -9,7 +9,7 @@ import { Tabs, TabItem } from "~/components"; ## Description -The `DurableObjectStub` interface is used to obtain a reference a Durable Object instance and invoke methods on that instance. The type of `DurableObjectStub` is generic to allow for RPC methods to be invoked on the stub. +The `DurableObjectStub` interface is used to obtain a reference a Durable Object and invoke methods on that instance. The type of `DurableObjectStub` is generic to allow for RPC methods to be invoked on the stub. @@ -33,7 +33,7 @@ export default { // Every unique ID refers to an individual instance of the Durable Object class const id = env.MY_DURABLE_OBJECT.idFromName("foo"); - // A stub is a client used to invoke methods on the Durable Object instance + // A stub is a client used to invoke methods on the Durable Object const stub = env.MY_DURABLE_OBJECT.get(id); // Methods on the Durable Object are invoked via the stub @@ -70,7 +70,7 @@ export default { // Every unique ID refers to an individual instance of the Durable Object class const id = env.MY_DURABLE_OBJECT.idFromName("foo"); - // A stub is a client used to invoke methods on the Durable Object instance + // A stub is a client used to invoke methods on the Durable Object const stub = env.MY_DURABLE_OBJECT.get(id); // Methods on the Durable Object are invoked via the stub diff --git a/src/content/docs/durable-objects/api/websockets.mdx b/src/content/docs/durable-objects/api/websockets.mdx index 05f65396d725a64..c30729b75084133 100644 --- a/src/content/docs/durable-objects/api/websockets.mdx +++ b/src/content/docs/durable-objects/api/websockets.mdx @@ -58,7 +58,7 @@ To learn more about WebSocket Hibernation, refer to [Build a WebSocket server wi - `tags` are optional string tags used to look up the WebSocket with `state.getWebSockets()`. Each tag is limited to 256 characters, and each WebSocket is limited to 10 tags associated with it. - - The WebSocket Hibernation API permits a maximum of 32,768 WebSocket connections per Durable Object instance, but the CPU and memory usage of a given workload may further limit the practical number of simultaneous connections. + - The WebSocket Hibernation API permits a maximum of 32,768 WebSocket connections per Durable Object, but the CPU and memory usage of a given workload may further limit the practical number of simultaneous connections. ### getWebSockets diff --git a/src/content/docs/durable-objects/examples/build-a-rate-limiter.mdx b/src/content/docs/durable-objects/examples/build-a-rate-limiter.mdx index 7282631d4196c10..7aec3637e7e5009 100644 --- a/src/content/docs/durable-objects/examples/build-a-rate-limiter.mdx +++ b/src/content/docs/durable-objects/examples/build-a-rate-limiter.mdx @@ -17,7 +17,7 @@ This example shows how to build a rate limiter using Durable Objects and Workers This example also discusses some decisions that need to be made when designing a system, such as a rate limiter, with Durable Objects. -The Worker creates a `RateLimiter` Durable Object on a per IP basis to protect upstream resources. IP based rate limiting can be effective without negatively impacting latency because any given IP will remain within a small geographic area colocated with the `RateLimiter` Durable Object instance. Furthermore, throughput is also improved because each IP gets its own Durable Object. +The Worker creates a `RateLimiter` Durable Object on a per IP basis to protect upstream resources. IP based rate limiting can be effective without negatively impacting latency because any given IP will remain within a small geographic area colocated with the `RateLimiter` Durable Object. Furthermore, throughput is also improved because each IP gets its own Durable Object. It might seem simpler to implement a global rate limiter, `const id = env.RATE_LIMITER.idFromName("global");`, which can provide better guarantees on the request rate to the upstream resource. However: diff --git a/src/content/docs/durable-objects/examples/websocket-hibernation-server.mdx b/src/content/docs/durable-objects/examples/websocket-hibernation-server.mdx index 3c8942259d84c10..5ac63fd8184f47b 100644 --- a/src/content/docs/durable-objects/examples/websocket-hibernation-server.mdx +++ b/src/content/docs/durable-objects/examples/websocket-hibernation-server.mdx @@ -41,7 +41,7 @@ export default { return new Response('Durable Object expected Upgrade: websocket', { status: 426 }); } - // This example will refer to the same Durable Object instance, + // This example will refer to the same Durable Object, // since the name "foo" is hardcoded. let id = env.WEBSOCKET_HIBERNATION_SERVER.idFromName("foo"); let stub = env.WEBSOCKET_HIBERNATION_SERVER.get(id); @@ -66,7 +66,7 @@ export class WebSocketHibernationServer extends DurableObject { // Creates two ends of a WebSocket connection. const webSocketPair = new WebSocketPair(); const [client, server] = Object.values(webSocketPair); - + // Calling `acceptWebSocket()` informs the runtime that this WebSocket is to begin terminating // request within the Durable Object. It has the effect of "accepting" the connection, // and allowing the WebSocket to send and receive messages. @@ -119,7 +119,7 @@ export default { return new Response('Durable Object expected Upgrade: websocket', { status: 426 }); } - // This example will refer to the same Durable Object instance, + // This example will refer to the same Durable Object, // since the name "foo" is hardcoded. let id = env.WEBSOCKET_HIBERNATION_SERVER.idFromName("foo"); let stub = env.WEBSOCKET_HIBERNATION_SERVER.get(id); @@ -144,7 +144,7 @@ export class WebSocketHibernationServer extends DurableObject { // Creates two ends of a WebSocket connection. const webSocketPair = new WebSocketPair(); const [client, server] = Object.values(webSocketPair); - + // Calling `acceptWebSocket()` informs the runtime that this WebSocket is to begin terminating // request within the Durable Object. It has the effect of "accepting" the connection, // and allowing the WebSocket to send and receive messages. diff --git a/src/content/docs/durable-objects/examples/websocket-server.mdx b/src/content/docs/durable-objects/examples/websocket-server.mdx index 8e3812927624fa4..a03748a687d22d8 100644 --- a/src/content/docs/durable-objects/examples/websocket-server.mdx +++ b/src/content/docs/durable-objects/examples/websocket-server.mdx @@ -39,7 +39,7 @@ export default { return new Response('Durable Object expected Upgrade: websocket', { status: 426 }); } - // This example will refer to the same Durable Object instance, + // This example will refer to the same Durable Object, // since the name "foo" is hardcoded. let id = env.WEBSOCKET_SERVER.idFromName("foo"); let stub = env.WEBSOCKET_SERVER.get(id); @@ -122,7 +122,7 @@ export default { return new Response('Durable Object expected Upgrade: websocket', { status: 426 }); } - // This example will refer to the same Durable Object instance, + // This example will refer to the same Durable Object, // since the name "foo" is hardcoded. let id = env.WEBSOCKET_SERVER.idFromName("foo"); let stub = env.WEBSOCKET_SERVER.get(id); diff --git a/src/content/docs/durable-objects/get-started/tutorial-with-sql-api.mdx b/src/content/docs/durable-objects/get-started/tutorial-with-sql-api.mdx index cfc02cef3aec8cc..1555f534cef3e12 100644 --- a/src/content/docs/durable-objects/get-started/tutorial-with-sql-api.mdx +++ b/src/content/docs/durable-objects/get-started/tutorial-with-sql-api.mdx @@ -128,7 +128,7 @@ export class MyDurableObject extends DurableObject { In the code above, you have: 1. Defined a RPC method, `sayHello()`, that can be called by a Worker to communicate with a Durable Object. 2. Accessed a Durable Object's attached storage, which is a private SQLite database only accesible to the object, using [SQL API](/durable-objects/api/storage-api/#sqlexec) methods (`sql.exec()`) available on `ctx.storage` . -3. Returned an object representing the single row query result using `one()`, which checks that the query result has exactly one row. +3. Returned an object representing the single row query result using `one()`, which checks that the query result has exactly one row. 4. Return the `greeting` column from the row object result. ## 4. Instantiate and communicate with a Durable Object @@ -136,7 +136,7 @@ In the code above, you have: :::note Durable Objects do not receive requests directly from the Internet. Durable Objects receive requests from Workers or other Durable Objects. -This is achieved by configuring a binding in the calling Worker for each Durable Object class that you would like it to be able to talk to. These bindings must be configured at upload time. Methods exposed by the binding can be used to communicate with particular Durable Object instances. +This is achieved by configuring a binding in the calling Worker for each Durable Object class that you would like it to be able to talk to. These bindings must be configured at upload time. Methods exposed by the binding can be used to communicate with particular Durable Objects. ::: A Worker is used to [access Durable Objects](/durable-objects/best-practices/create-durable-object-stubs-and-send-requests/). @@ -213,7 +213,7 @@ The `[[durable_objects.bindings]]` section contains the following fields: ## 6. Configure Durable Object class with SQLite storage backend -A migration is a mapping process from a class name to a runtime state. You perform a migration when creating a new Durable Object class, or when renaming, deleting or transferring an existing Durable Object class. +A migration is a mapping process from a class name to a runtime state. You perform a migration when creating a new Durable Object class, or when renaming, deleting or transferring an existing Durable Object class. Migrations are performed through the `[[migrations]]` configurations key in your `wrangler.toml` file. diff --git a/src/content/docs/durable-objects/get-started/walkthrough.mdx b/src/content/docs/durable-objects/get-started/walkthrough.mdx index 6efea571227b8c0..b6e9c8e147cef1e 100644 --- a/src/content/docs/durable-objects/get-started/walkthrough.mdx +++ b/src/content/docs/durable-objects/get-started/walkthrough.mdx @@ -139,7 +139,7 @@ The `fetch()` handler allows you to instantiate and communicate to a Durable Obj :::note Durable Objects do not receive requests directly from the Internet. Durable Objects receive requests from Workers or other Durable Objects. -This is achieved by configuring a binding in the calling Worker for each Durable Object class that you would like it to be able to talk to. These bindings must be configured at upload time. Methods exposed by the binding can be used to communicate with particular Durable Object instances. +This is achieved by configuring a binding in the calling Worker for each Durable Object class that you would like it to be able to talk to. These bindings must be configured at upload time. Methods exposed by the binding can be used to communicate with particular Durable Objects. ::: To communicate with a Durable Object, the fetch handler should look like the following: diff --git a/src/content/docs/durable-objects/platform/known-issues.mdx b/src/content/docs/durable-objects/platform/known-issues.mdx index 03574f91c744bd5..7fe2020e3ac4981 100644 --- a/src/content/docs/durable-objects/platform/known-issues.mdx +++ b/src/content/docs/durable-objects/platform/known-issues.mdx @@ -12,7 +12,7 @@ Global uniqueness guarantees there is only a single instance of a Durable Object Uniqueness is enforced upon starting a new event (such as receiving an HTTP request), and upon accessing storage. -After an event is received, if the event takes some time to execute and does not ever access its durable storage, then it is possible that the Durable Object instance may no longer be current, and some other instance of the same Durable Object ID will have been created elsewhere. If the event accesses storage at this point, it will receive an [exception](/durable-objects/observability/troubleshooting/). If the event completes without ever accessing storage, it may not ever realize that the Durable Object was no longer current. +After an event is received, if the event takes some time to execute and does not ever access its durable storage, then it is possible that the Durable Object may no longer be current, and some other instance of the same Durable Object ID will have been created elsewhere. If the event accesses storage at this point, it will receive an [exception](/durable-objects/observability/troubleshooting/). If the event completes without ever accessing storage, it may not ever realize that the Durable Object was no longer current. A Durable Object may be replaced in the event of a network partition or a software update (including either an update of the Durable Object's class code, or of the Workers system itself). Enabling `wrangler tail` or [Cloudflare dashboard](https://dash.cloudflare.com/) logs requires a software update. diff --git a/src/content/docs/durable-objects/reference/data-location.mdx b/src/content/docs/durable-objects/reference/data-location.mdx index 649c38dcb33daf0..60f1ce63c866896 100644 --- a/src/content/docs/durable-objects/reference/data-location.mdx +++ b/src/content/docs/durable-objects/reference/data-location.mdx @@ -7,7 +7,7 @@ sidebar: ## Restrict Durable Objects to a jurisdiction -Jurisdictions are used to create Durable Object instances that only run and store data within a region to comply with local regulations such as the [GDPR](https://gdpr-info.eu/) or [FedRAMP](https://blog.cloudflare.com/cloudflare-achieves-fedramp-authorization/). +Jurisdictions are used to create Durable Objects that only run and store data within a region to comply with local regulations such as the [GDPR](https://gdpr-info.eu/) or [FedRAMP](https://blog.cloudflare.com/cloudflare-achieves-fedramp-authorization/). Workers may still access Durable Objects constrained to a jurisdiction from anywhere in the world. The jurisdiction constraint only controls where the Durable Object itself runs and persists data. Consider using [Regional Services](/data-localization/regional-services/) to control the regions from which Cloudflare responds to requests. @@ -17,7 +17,7 @@ A [`DurableObjectId`](/durable-objects/api/id) will be logged outside of the spe ::: -Durable Object instances can be restricted to a specific jurisdiction either by creating a [`DurableObjectNamespace`](/durable-objects/api/namespace/) restricted to a jurisdiction, or by creating an individual [`DurableObjectId`](/durable-objects/api/id) restricted to a jurisdiction: +Durable Objects can be restricted to a specific jurisdiction either by creating a [`DurableObjectNamespace`](/durable-objects/api/namespace/) restricted to a jurisdiction, or by creating an individual [`DurableObjectId`](/durable-objects/api/id) restricted to a jurisdiction: ```js const euSubnamespace = env.MY_DURABLE_OBJECT.jurisdiction("eu"); diff --git a/src/content/docs/durable-objects/reference/durable-objects-migrations.mdx b/src/content/docs/durable-objects/reference/durable-objects-migrations.mdx index 7d55c4ea7411ee9..30124ba3e634c14 100644 --- a/src/content/docs/durable-objects/reference/durable-objects-migrations.mdx +++ b/src/content/docs/durable-objects/reference/durable-objects-migrations.mdx @@ -49,7 +49,7 @@ Migrations can also be used to delete a Durable Object class and its stored Dura :::caution[Delete migrations] -Running a delete migration will delete all Durable Object instances associated with the deleted class, including all of their stored data. Do not run a delete migration on a class without first ensuring that you are not relying on the Durable Objects within that class anymore. Copy any important data to some other location before deleting. +Running a delete migration will delete all Durable Objects associated with the deleted class, including all of their stored data. Do not run a delete migration on a class without first ensuring that you are not relying on the Durable Objects within that class anymore. Copy any important data to some other location before deleting. ::: diff --git a/src/content/docs/durable-objects/reference/websockets.mdx b/src/content/docs/durable-objects/reference/websockets.mdx index 514feabf96c2c45..b9e4f663eb0157e 100644 --- a/src/content/docs/durable-objects/reference/websockets.mdx +++ b/src/content/docs/durable-objects/reference/websockets.mdx @@ -33,7 +33,7 @@ Hibernation is only supported when a Durable Object acts as a WebSocket server. ::: -A Durable Object with WebSockets created via the Hibernation API will not incur billable [Duration (GB-s) charges](/durable-objects/platform/pricing/) during periods of inactivity, unlike Durable Objects using the [regular WebSockets API](/workers/runtime-apis/websockets/). Note that other events, for example [alarms](/durable-objects/api/alarms/), can prevent a Durable Object instance from being inactive and therefore prevent this cost savings. +A Durable Object with WebSockets created via the Hibernation API will not incur billable [Duration (GB-s) charges](/durable-objects/platform/pricing/) during periods of inactivity, unlike Durable Objects using the [regular WebSockets API](/workers/runtime-apis/websockets/). Note that other events, for example [alarms](/durable-objects/api/alarms/), can prevent a Durable Object from being inactive and therefore prevent this cost savings. The WebSocket Hibernation API includes: diff --git a/src/content/docs/workers/configuration/versions-and-deployments/gradual-deployments.mdx b/src/content/docs/workers/configuration/versions-and-deployments/gradual-deployments.mdx index 333cc558fbc3e90..d5a8fa81771e0b3 100644 --- a/src/content/docs/workers/configuration/versions-and-deployments/gradual-deployments.mdx +++ b/src/content/docs/workers/configuration/versions-and-deployments/gradual-deployments.mdx @@ -199,7 +199,7 @@ curl -s https://example.com -H 'Cloudflare-Workers-Version-Overrides: my-worker- 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. -When you create a new gradual deployment for a Durable Object Worker, each Durable Object instance 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. +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. ![Gradual Deployments Durable Objects](~/assets/images/workers/platform/versions-and-deployments/durable-objects.png) diff --git a/src/content/docs/workers/platform/changelog/historical-changelog.mdx b/src/content/docs/workers/platform/changelog/historical-changelog.mdx index 30fead57c0dee1b..baf231a8858cd52 100644 --- a/src/content/docs/workers/platform/changelog/historical-changelog.mdx +++ b/src/content/docs/workers/platform/changelog/historical-changelog.mdx @@ -307,7 +307,7 @@ Changes this week: Changes this week: * Turn on V8 Sparkplug compiler. -* Durable Object instances that are finishing up existing requests after their code is updated will be disconnected from the persistent storage API, to maintain the invariant that only a single instance ever has access to persistent storage for a given Durable Object. +* Durable Objects that are finishing up existing requests after their code is updated will be disconnected from the persistent storage API, to maintain the invariant that only a single instance ever has access to persistent storage for a given Durable Object. ## 2021-06-04 diff --git a/src/content/docs/workers/testing/index.mdx b/src/content/docs/workers/testing/index.mdx index 0f5b6eaa462cd7c..4ede7ed43eceb8f 100644 --- a/src/content/docs/workers/testing/index.mdx +++ b/src/content/docs/workers/testing/index.mdx @@ -22,7 +22,7 @@ Review the tools available for testing and debugging Workers. | Isolated per-test storage | ✅ | ❌ | ❌ | | Outbound request mocking | ✅ | ❌ | ✅ | | Multiple Worker support | ✅ | 🚧[^1] | ✅ | -| Direct access to Durable Object instances | ✅ | ❌ | ❌ | +| Direct access to Durable Objects | ✅ | ❌ | ❌ | | Run Durable Object alarms immediately | ✅ | ❌ | ❌ | | List Durable Objects | ✅ | ❌ | ❌ | | Testing service Workers | ❌ | ✅ | ✅ | diff --git a/src/content/docs/workers/testing/vitest-integration/get-started/migrate-from-miniflare-2.mdx b/src/content/docs/workers/testing/vitest-integration/get-started/migrate-from-miniflare-2.mdx index 3d1e31e71e4e2e2..6d001019f531121 100644 --- a/src/content/docs/workers/testing/vitest-integration/get-started/migrate-from-miniflare-2.mdx +++ b/src/content/docs/workers/testing/vitest-integration/get-started/migrate-from-miniflare-2.mdx @@ -149,7 +149,7 @@ The `getMiniflareFetchMock()` function has been replaced with the new `fetchMock ## Use Durable Object helpers -The `getMiniflareDurableObjectStorage()`, `getMiniflareDurableObjectState()`, `getMiniflareDurableObjectInstance()`, and `runWithMiniflareDurableObjectGates()` functions have all been replaced with a single `runInDurableObject()` function from the `cloudflare:test` module. The `runInDurableObject()` function accepts a `DurableObjectStub` with a callback accepting the Durable Object instance and corresponding `DurableObjectState` as arguments. Consolidating these functions into a single function simplifies the API surface, and ensures instances are accessed with the correct request context and [gating behavior](https://blog.cloudflare.com/durable-objects-easy-fast-correct-choose-three/). Refer to the [Test APIs page](/workers/testing/vitest-integration/test-apis/) for more details. +The `getMiniflareDurableObjectStorage()`, `getMiniflareDurableObjectState()`, `getMiniflareDurableObjectInstance()`, and `runWithMiniflareDurableObjectGates()` functions have all been replaced with a single `runInDurableObject()` function from the `cloudflare:test` module. The `runInDurableObject()` function accepts a `DurableObjectStub` with a callback accepting the Durable Object and corresponding `DurableObjectState` as arguments. Consolidating these functions into a single function simplifies the API surface, and ensures instances are accessed with the correct request context and [gating behavior](https://blog.cloudflare.com/durable-objects-easy-fast-correct-choose-three/). Refer to the [Test APIs page](/workers/testing/vitest-integration/test-apis/) for more details. ```diff + import { env, runInDurableObject } from "cloudflare:test"; diff --git a/src/content/docs/workers/testing/vitest-integration/test-apis.mdx b/src/content/docs/workers/testing/vitest-integration/test-apis.mdx index 9d62ce42414e356..4cf9120b07a9b38 100644 --- a/src/content/docs/workers/testing/vitest-integration/test-apis.mdx +++ b/src/content/docs/workers/testing/vitest-integration/test-apis.mdx @@ -180,11 +180,11 @@ The Workers Vitest integration provides runtime helpers for writing tests in the * runInDurableObject\(stub:DurableObjectStub, callback:(instance: O, state: DurableObjectState) => R | Promise\): Promise\ - * Runs the provided `callback` inside the Durable Object instance that corresponds to the provided `stub`. + * Runs the provided `callback` inside the Durable Object that corresponds to the provided `stub`.
- This temporarily replaces your Durable Object's `fetch()` handler with `callback`, then sends a request to it, returning the result. This can be used to call/spy-on Durable Object instance methods or seed/get persisted data. Note this can only be used with `stub`s pointing to Durable Objects defined in the `main` Worker. + This temporarily replaces your Durable Object's `fetch()` handler with `callback`, then sends a request to it, returning the result. This can be used to call/spy-on Durable Object methods or seed/get persisted data. Note this can only be used with `stub`s pointing to Durable Objects defined in the `main` Worker.
diff --git a/src/content/glossary/durable-objects.yaml b/src/content/glossary/durable-objects.yaml index a35a04ca5651c63..1a32faf3c5df0d8 100644 --- a/src/content/glossary/durable-objects.yaml +++ b/src/content/glossary/durable-objects.yaml @@ -3,7 +3,7 @@ productName: Durable Objects entries: - term: "Durable Objects" general_definition: |- - The product name, or the collective noun referring to more than one Durable Object instance. + The product name, or the collective noun referring to more than one Durable Object. - term: "namespace" general_definition: |- @@ -35,7 +35,7 @@ entries: - term: "Storage API" general_definition: |- - The transactional and strongly consistent (serializable) [Storage API](/durable-objects/api/storage-api/) for persisting data within each Durable Object instance. State stored within a unique DO instance is "private" to that Durable Object, and not accessible from other Durable Objects. + The transactional and strongly consistent (serializable) [Storage API](/durable-objects/api/storage-api/) for persisting data within each Durable Object. State stored within a unique Durable Object is "private" to that Durable Object, and not accessible from other Durable Objects. Storage API includes key-value (KV) API, SQL API, and point-in-time-recovery (PITR) API. @@ -66,4 +66,4 @@ entries: - term: "event context" general_definition: |- - The duration of time that a Durable Object instance is processing an event, such as a remote procedure call. Compute duration charges are incurred for the duration of the event context. \ No newline at end of file + The duration of time that a Durable Object is processing an event, such as a remote procedure call. Compute duration charges are incurred for the duration of the event context. \ No newline at end of file From abbf4b2fd6b12977d1a22cf9b12229b32a888798 Mon Sep 17 00:00:00 2001 From: Jun Lee Date: Fri, 11 Oct 2024 15:57:19 +0100 Subject: [PATCH 07/10] Fixing broken method formatting. --- .../docs/durable-objects/api/websockets.mdx | 38 ++++--------------- 1 file changed, 7 insertions(+), 31 deletions(-) diff --git a/src/content/docs/durable-objects/api/websockets.mdx b/src/content/docs/durable-objects/api/websockets.mdx index c30729b75084133..3504ebf3211c2f9 100644 --- a/src/content/docs/durable-objects/api/websockets.mdx +++ b/src/content/docs/durable-objects/api/websockets.mdx @@ -27,10 +27,7 @@ To learn more about WebSocket Hibernation, refer to [Build a WebSocket server wi ### serializeAttachment -- - serializeAttachment(value ) - - : +- serializeAttachment(value ): - Keeps a copy of `value` in memory (not on disk) to survive hibernation. The value can be any type supported by the [structured clone algorithm](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm), which is true of most types. @@ -46,11 +43,7 @@ To learn more about WebSocket Hibernation, refer to [Build a WebSocket server wi ### acceptWebSocket -- - acceptWebSocket(ws , tags{" "} - ) - - : +- acceptWebSocket(ws , tags{" "} ): - Adds a WebSocket to the set attached to this Durable Object. `ws.accept()` must not have been called separately. Once called, any incoming messages will be delivered by calling the Durable Object's `webSocketMessage()` handler, and `webSocketClose()` will be invoked upon disconnect. @@ -62,10 +55,7 @@ To learn more about WebSocket Hibernation, refer to [Build a WebSocket server wi ### getWebSockets -- - getWebSockets(tag ) - - : +- getWebSockets(tag ): - Gets an array of accepted WebSockets matching the given tag. Disconnected WebSockets 1 are automatically removed from the list. Calling `state.getWebSockets()` with no `tag` argument will return all WebSockets. @@ -78,20 +68,13 @@ To learn more about WebSocket Hibernation, refer to [Build a WebSocket server wi ### getTags -- - getTags(ws ) - - : +- getTags(ws ): - Returns an Array of tags associated with the given WebSocket. Throws an error if you have not called `state.acceptWebSocket()` on the given WebSocket. ### setWebSocketAutoResponse -- - setWebSocketAutoResponse(webSocketRequestResponsePair{" "} - ) - - : +- setWebSocketAutoResponse(webSocketRequestResponsePair{" "} ): - Sets an application level auto response that does not wake hibernated WebSockets. @@ -113,20 +96,13 @@ To learn more about WebSocket Hibernation, refer to [Build a WebSocket server wi ### getWebSocketAutoResponseTimestamp -- - getWebSocketAutoResponseTimestamp(ws ) - - : +- getWebSocketAutoResponseTimestamp(ws ): - Gets the most recent `Date` when the WebSocket received an auto-response request, or `null` if the given WebSocket never received an auto-response request. ### setHibernatableWebSocketEventTimeout -- - setHibernatableWebSocketEventTimeout(timeout {" "} - ) - - : +- setHibernatableWebSocketEventTimeout(timeout {" "}): - Sets the maximum amount of milliseconds a WebSocket event (refer to the handler methods below) can run for. From 8ecba0981cfae751127f2466ce081fa18397f8a2 Mon Sep 17 00:00:00 2001 From: Jun Lee Date: Fri, 11 Oct 2024 16:23:09 +0100 Subject: [PATCH 08/10] Temporarily reverting files to avoid merge conflict. --- src/content/docs/durable-objects/api/id.mdx | 6 +++--- src/content/docs/durable-objects/api/namespace.mdx | 14 +++++++------- src/content/docs/durable-objects/api/stub.mdx | 6 +++--- .../durable-objects/get-started/walkthrough.mdx | 2 +- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/content/docs/durable-objects/api/id.mdx b/src/content/docs/durable-objects/api/id.mdx index 29d492aa7f69a26..97c339ff62fa022 100644 --- a/src/content/docs/durable-objects/api/id.mdx +++ b/src/content/docs/durable-objects/api/id.mdx @@ -9,13 +9,13 @@ import { Tabs, TabItem } from "~/components"; ## Description -The `DurableObjectId` interface refers to a new or existing Durable Object. This interface is most frequently used by [`DurableObjectNamespace::get`](/durable-objects/api/namespace/#get) to obtain a stub for submitting requests to a Durable Object. +The `DurableObjectId` interface refers to a new or existing Durable Object instance. This interface is most frequently used by [`DurableObjectNamespace::get`](/durable-objects/api/namespace/#get) to obtain a stub for submitting requests to a Durable Object instance. -Note that creating an ID for a Durable Object does not create the Durable Object. The Durable Object is created lazily after calling [`DurableObjectNamespace::get`](/durable-objects/api/namespace/#get) to create a [`DurableObjectStub`](/durable-objects/api/stub) from a `DurableObjectId`. This ensures that objects are not constructed until they are actually accessed. +Note that creating an ID for a Durable Object instance does not create the Durable Object. The Durable Object is created lazily after calling [`DurableObjectNamespace::get`](/durable-objects/api/namespace/#get) to create a [`DurableObjectStub`](/durable-objects/api/stub) from a `DurableObjectId`. This ensures that objects are not constructed until they are actually accessed. :::note[`DurableObjectId`] -If you are experiencing an issue with a particular Durable Object, you may wish to log the `DurableObjectId` from your Worker and include it in your Cloudflare support request. +If you are experiencing an issue with a particular Durable Object instance, you may wish to log the `DurableObjectId` from your Worker and include it in your Cloudflare support request. ::: diff --git a/src/content/docs/durable-objects/api/namespace.mdx b/src/content/docs/durable-objects/api/namespace.mdx index aef707d2eac81b4..4e53d3398dc9131 100644 --- a/src/content/docs/durable-objects/api/namespace.mdx +++ b/src/content/docs/durable-objects/api/namespace.mdx @@ -9,9 +9,9 @@ import { Tabs, TabItem } from "~/components"; ## Description -The `DurableObjectNamespace` interface is used to obtain a reference to a new or existing Durable Object. The interface is accessible from the fetch handler on a Cloudflare Worker via the `env` parameter, which is the standard interface when referencing bindings declared in `wrangler.toml`. +The `DurableObjectNamespace` interface is used to obtain a reference to a new or existing Durable Object instance. The interface is accessible from the fetch handler on a Cloudflare Worker via the `env` parameter, which is the standard interface when referencing bindings declared in `wrangler.toml`. -This interface defines several [methods](/durable-objects/api/namespace/#methods) that can be used to create an ID for a Durable Object. Note that creating an ID for a Durable Object does not create the Durable Object. The Durable Object is created lazily after calling [`DurableObjectNamespace::get`](/durable-objects/api/namespace/#get) to create a [`DurableObjectStub`](/durable-objects/api/stub) from a `DurableObjectId`. This ensures that objects are not constructed until they are actually accessed. +This interface defines several [methods](/durable-objects/api/namespace/#methods) that can be used to create an ID for a Durable Object instance. Note that creating an ID for a Durable Object instance does not create the Durable Object. The Durable Object is created lazily after calling [`DurableObjectNamespace::get`](/durable-objects/api/namespace/#get) to create a [`DurableObjectStub`](/durable-objects/api/stub) from a `DurableObjectId`. This ensures that objects are not constructed until they are actually accessed. @@ -29,7 +29,7 @@ export default { // Every unique ID refers to an individual instance of the Durable Object class const id = env.MY_DURABLE_OBJECT.idFromName("foo"); - // A stub is a client Object used to invoke methods defined by the Durable Object + // A stub is a client Object used to invoke methods defined by the Durable Object instance const stub = env.MY_DURABLE_OBJECT.get(id); ... } @@ -56,7 +56,7 @@ export default { // Every unique ID refers to an individual instance of the Durable Object class const id = env.MY_DURABLE_OBJECT.idFromName("foo"); - // A stub is a client Object used to invoke methods defined by the Durable Object + // A stub is a client Object used to invoke methods defined by the Durable Object instance const stub = env.MY_DURABLE_OBJECT.get(id); ... } @@ -78,7 +78,7 @@ const barId = env.MY_DURABLE_OBJECT.idFromName("bar"); #### Parameters -- A required string to be used to generate a [`DurableObjectId`](/durable-objects/api/id) corresponding to the name of a Durable Object. +- A required string to be used to generate a [`DurableObjectId`](/durable-objects/api/id) corresponding to the name of a Durable Object instance. #### Return values @@ -130,7 +130,7 @@ const id = env.MY_DURABLE_OBJECT.idFromString(session_id); ### `get` -`get` obtains a [`DurableObjectStub`](/durable-objects/api/stub) from a [`DurableObjectId`](/durable-objects/api/id) which can be used to invoke methods on a Durable Object. +`get` obtains a [`DurableObjectStub`](/durable-objects/api/stub) from a [`DurableObjectId`](/durable-objects/api/id) which can be used to invoke methods on a Durable Object instance. ```js const id = env.MY_DURABLE_OBJECT.newUniqueId(); @@ -147,7 +147,7 @@ const stub = env.MY_DURABLE_OBJECT.get(id); ### `jurisdiction` -`jurisdiction` creates a subnamespace from a namespace where all Durable Object IDs and references created from that subnamespace will be restricted to the specified [jurisdiction](/durable-objects/reference/data-location/#restrict-durable-objects-to-a-jurisdiction). +`jurisdiction` creates a subnamespace from a namespace where all Durable Object instance IDs and references created from that subnamespace will be restricted to the specified [jurisdiction](/durable-objects/reference/data-location/#restrict-durable-objects-to-a-jurisdiction). ```js const subnamespace = env.MY_DURABLE_OBJECT.jurisdiction("foo"); diff --git a/src/content/docs/durable-objects/api/stub.mdx b/src/content/docs/durable-objects/api/stub.mdx index 68e78a54d821ae8..19dfbd9cc724082 100644 --- a/src/content/docs/durable-objects/api/stub.mdx +++ b/src/content/docs/durable-objects/api/stub.mdx @@ -9,7 +9,7 @@ import { Tabs, TabItem } from "~/components"; ## Description -The `DurableObjectStub` interface is used to obtain a reference a Durable Object and invoke methods on that instance. The type of `DurableObjectStub` is generic to allow for RPC methods to be invoked on the stub. +The `DurableObjectStub` interface is used to obtain a reference a Durable Object instance and invoke methods on that instance. The type of `DurableObjectStub` is generic to allow for RPC methods to be invoked on the stub. @@ -33,7 +33,7 @@ export default { // Every unique ID refers to an individual instance of the Durable Object class const id = env.MY_DURABLE_OBJECT.idFromName("foo"); - // A stub is a client used to invoke methods on the Durable Object + // A stub is a client used to invoke methods on the Durable Object instance const stub = env.MY_DURABLE_OBJECT.get(id); // Methods on the Durable Object are invoked via the stub @@ -70,7 +70,7 @@ export default { // Every unique ID refers to an individual instance of the Durable Object class const id = env.MY_DURABLE_OBJECT.idFromName("foo"); - // A stub is a client used to invoke methods on the Durable Object + // A stub is a client used to invoke methods on the Durable Object instance const stub = env.MY_DURABLE_OBJECT.get(id); // Methods on the Durable Object are invoked via the stub diff --git a/src/content/docs/durable-objects/get-started/walkthrough.mdx b/src/content/docs/durable-objects/get-started/walkthrough.mdx index b6e9c8e147cef1e..6efea571227b8c0 100644 --- a/src/content/docs/durable-objects/get-started/walkthrough.mdx +++ b/src/content/docs/durable-objects/get-started/walkthrough.mdx @@ -139,7 +139,7 @@ The `fetch()` handler allows you to instantiate and communicate to a Durable Obj :::note Durable Objects do not receive requests directly from the Internet. Durable Objects receive requests from Workers or other Durable Objects. -This is achieved by configuring a binding in the calling Worker for each Durable Object class that you would like it to be able to talk to. These bindings must be configured at upload time. Methods exposed by the binding can be used to communicate with particular Durable Objects. +This is achieved by configuring a binding in the calling Worker for each Durable Object class that you would like it to be able to talk to. These bindings must be configured at upload time. Methods exposed by the binding can be used to communicate with particular Durable Object instances. ::: To communicate with a Durable Object, the fetch handler should look like the following: From 4e503cef2f183fea53a438a15e5971f722014692 Mon Sep 17 00:00:00 2001 From: Jun Lee Date: Fri, 11 Oct 2024 16:27:15 +0100 Subject: [PATCH 09/10] Durable Object instance -> Durable Object --- src/content/docs/durable-objects/api/id.mdx | 6 ++--- .../docs/durable-objects/api/namespace.mdx | 24 +++++++++---------- src/content/docs/durable-objects/api/stub.mdx | 4 ++-- ...durable-object-stubs-and-send-requests.mdx | 8 +++---- .../get-started/walkthrough.mdx | 8 +++---- .../partials/durable-objects/example-rpc.mdx | 4 ++-- 6 files changed, 27 insertions(+), 27 deletions(-) diff --git a/src/content/docs/durable-objects/api/id.mdx b/src/content/docs/durable-objects/api/id.mdx index 255f77699c1b210..f3cfb0fa6eacd36 100644 --- a/src/content/docs/durable-objects/api/id.mdx +++ b/src/content/docs/durable-objects/api/id.mdx @@ -9,13 +9,13 @@ import { Render, Tabs, TabItem } from "~/components"; ## Description -A Durable Object ID is a 64-digit hexadecimal number used to identify a Durable Object instance. Not all 64-digit hex numbers are valid IDs. Durable Object IDs are constructed indirectly via the [`DurableObjectNamespace`](/durable-objects/api/namespace) interface. +A Durable Object ID is a 64-digit hexadecimal number used to identify a Durable Object. Not all 64-digit hex numbers are valid IDs. Durable Object IDs are constructed indirectly via the [`DurableObjectNamespace`](/durable-objects/api/namespace) interface. -The `DurableObjectId` interface refers to a new or existing Durable Object instance. This interface is most frequently used by [`DurableObjectNamespace::get`](/durable-objects/api/namespace/#get) to obtain a [`DurableObjectStub`](/durable-objects/api/stub) for submitting requests to a Durable Object instance. Note that creating an ID for a Durable Object instance does not create the Durable Object. The Durable Object is created lazily after creating a stub from a `DurableObjectId`. This ensures that objects are not constructed until they are actually accessed. +The `DurableObjectId` interface refers to a new or existing Durable Object. This interface is most frequently used by [`DurableObjectNamespace::get`](/durable-objects/api/namespace/#get) to obtain a [`DurableObjectStub`](/durable-objects/api/stub) for submitting requests to a Durable Object. Note that creating an ID for a Durable Object does not create the Durable Object. The Durable Object is created lazily after creating a stub from a `DurableObjectId`. This ensures that objects are not constructed until they are actually accessed. :::note[Logging] -If you are experiencing an issue with a particular Durable Object instance, you may wish to log the `DurableObjectId` from your Worker and include it in your Cloudflare support request. +If you are experiencing an issue with a particular Durable Object, you may wish to log the `DurableObjectId` from your Worker and include it in your Cloudflare support request. ::: diff --git a/src/content/docs/durable-objects/api/namespace.mdx b/src/content/docs/durable-objects/api/namespace.mdx index 946c10aad081c2c..1f94375a4a34a4a 100644 --- a/src/content/docs/durable-objects/api/namespace.mdx +++ b/src/content/docs/durable-objects/api/namespace.mdx @@ -9,11 +9,11 @@ import { Render, Tabs, TabItem } from "~/components"; ## Description -A Durable Object namespace is a set of Durable Object instances that are backed by the same Durable Object class. There is only one Durable Object namespace per class. A Durable Object namespace can contain any number of Durable Object instances. +A Durable Object namespace is a set of Durable Objects that are backed by the same Durable Object class. There is only one Durable Object namespace per class. A Durable Object namespace can contain any number of Durable Objects. -The `DurableObjectNamespace` interface is used to obtain a reference to new or existing Durable Object instances. The interface is accessible from the fetch handler on a Cloudflare Worker via the `env` parameter, which is the standard interface when referencing bindings declared in `wrangler.toml`. +The `DurableObjectNamespace` interface is used to obtain a reference to new or existing Durable Objects. The interface is accessible from the fetch handler on a Cloudflare Worker via the `env` parameter, which is the standard interface when referencing bindings declared in `wrangler.toml`. -This interface defines several [methods](/durable-objects/api/namespace/#methods) that can be used to create an ID for a Durable Object instance. Note that creating an ID for a Durable Object instance does not create the Durable Object. The Durable Object is created lazily after calling [`DurableObjectNamespace::get`](/durable-objects/api/namespace/#get) to create a [`DurableObjectStub`](/durable-objects/api/stub) from a `DurableObjectId`. This ensures that objects are not constructed until they are actually accessed. +This interface defines several [methods](/durable-objects/api/namespace/#methods) that can be used to create an ID for a Durable Object. Note that creating an ID for a Durable Object does not create the Durable Object. The Durable Object is created lazily after calling [`DurableObjectNamespace::get`](/durable-objects/api/namespace/#get) to create a [`DurableObjectStub`](/durable-objects/api/stub) from a `DurableObjectId`. This ensures that objects are not constructed until they are actually accessed. @@ -31,7 +31,7 @@ export default { // Every unique ID refers to an individual instance of the Durable Object class const id = env.MY_DURABLE_OBJECT.idFromName("foo"); - // A stub is a client Object used to invoke methods defined by the Durable Object instance + // A stub is a client Object used to invoke methods defined by the Durable Object const stub = env.MY_DURABLE_OBJECT.get(id); ... } @@ -58,7 +58,7 @@ export default { // Every unique ID refers to an individual instance of the Durable Object class const id = env.MY_DURABLE_OBJECT.idFromName("foo"); - // A stub is a client Object used to invoke methods defined by the Durable Object instance + // A stub is a client Object used to invoke methods defined by the Durable Object const stub = env.MY_DURABLE_OBJECT.get(id); ... } @@ -71,7 +71,7 @@ export default { ### `idFromName` -`idFromName` creates a unique [`DurableObjectId`](/durable-objects/api/id) which refers to an individual instance of the Durable Object class. Named Durable Object instances are the most common method of referring to Durable Object instances. +`idFromName` creates a unique [`DurableObjectId`](/durable-objects/api/id) which refers to an individual instance of the Durable Object class. Named Durable Objects are the most common method of referring to Durable Objects. ```js const fooId = env.MY_DURABLE_OBJECT.idFromName("foo"); @@ -80,7 +80,7 @@ const barId = env.MY_DURABLE_OBJECT.idFromName("bar"); #### Parameters -- A required string to be used to generate a [`DurableObjectId`](/durable-objects/api/id) corresponding to the name of a Durable Object instance. +- A required string to be used to generate a [`DurableObjectId`](/durable-objects/api/id) corresponding to the name of a Durable Object. #### Return values @@ -88,7 +88,7 @@ const barId = env.MY_DURABLE_OBJECT.idFromName("bar"); ### `newUniqueId` -`newUniqueId` creates a randomly generated and unique [`DurableObjectId`](/durable-objects/api/id) which refers to an individual instance of the Durable Object class. IDs created using `newUniqueId`, will need to be stored as a string in order to refer to the same Durable Object again in the future. For example, the ID can be stored in Workers KV, another Durable Object instance, or in a cookie in the user's browser. +`newUniqueId` creates a randomly generated and unique [`DurableObjectId`](/durable-objects/api/id) which refers to an individual instance of the Durable Object class. IDs created using `newUniqueId`, will need to be stored as a string in order to refer to the same Durable Object again in the future. For example, the ID can be stored in Workers KV, another Durable Object, or in a cookie in the user's browser. ```js const id = env.MY_DURABLE_OBJECT.newUniqueId(); @@ -99,7 +99,7 @@ const euId = env.MY_DURABLE_OBJECT.newUniqueId({ jurisdiction: "eu" }); The first time you get a Durable Object stub based on an ID derived from a name, the system has to take into account the possibility that a Worker on the opposite side of the world could have coincidentally accessed the same named Durable Object at the same time. To guarantee that only one instance of the Durable Object is created, the system must check that the Durable Object has not been created anywhere else. Due to the inherent limit of the speed of light, this round-the-world check can take up to a few hundred milliseconds. `newUniqueId` can skip this check. -After this first use, the location of the Durable Object instance will be cached around the world so that subsequent lookups are faster. +After this first use, the location of the Durable Object will be cached around the world so that subsequent lookups are faster. ::: @@ -127,9 +127,9 @@ After this first use, the location of the Durable Object instance will be cached ### `get` -`get` obtains a [`DurableObjectStub`](/durable-objects/api/stub) from a [`DurableObjectId`](/durable-objects/api/id) which can be used to invoke methods on a Durable Object instance. +`get` obtains a [`DurableObjectStub`](/durable-objects/api/stub) from a [`DurableObjectId`](/durable-objects/api/id) which can be used to invoke methods on a Durable Object. -This method returns the stub immediately, often before a connection has been established to the Durable Object instance. This allows requests to be sent to the instance right away, without waiting for a network round trip. +This method returns the stub immediately, often before a connection has been established to the Durable Object. This allows requests to be sent to the instance right away, without waiting for a network round trip. ```js const id = env.MY_DURABLE_OBJECT.newUniqueId(); @@ -147,7 +147,7 @@ const stub = env.MY_DURABLE_OBJECT.get(id); ### `jurisdiction` -`jurisdiction` creates a subnamespace from a namespace where all Durable Object instance IDs and references created from that subnamespace will be restricted to the specified [jurisdiction](/durable-objects/reference/data-location/#restrict-durable-objects-to-a-jurisdiction). +`jurisdiction` creates a subnamespace from a namespace where all Durable Object IDs and references created from that subnamespace will be restricted to the specified [jurisdiction](/durable-objects/reference/data-location/#restrict-durable-objects-to-a-jurisdiction). ```js const subnamespace = env.MY_DURABLE_OBJECT.jurisdiction("foo"); diff --git a/src/content/docs/durable-objects/api/stub.mdx b/src/content/docs/durable-objects/api/stub.mdx index bebf9de97b50200..0e5c306b4fe9c20 100644 --- a/src/content/docs/durable-objects/api/stub.mdx +++ b/src/content/docs/durable-objects/api/stub.mdx @@ -9,11 +9,11 @@ import { Render } from "~/components"; ## Description -The `DurableObjectStub` interface is a client used to invoke methods on a remote Durable Object instance. The type of `DurableObjectStub` is generic to allow for RPC methods to be invoked on the stub. +The `DurableObjectStub` interface is a client used to invoke methods on a remote Durable Object. The type of `DurableObjectStub` is generic to allow for RPC methods to be invoked on the stub. Durable Objects implement E-order semantics, a concept deriving from the [E distributed programming language](). When you make multiple calls to the same Durable Object, it is guaranteed that the calls will be delivered to the remote Durable Object in the order in which you made them. E-order semantics makes many distributed programming problems easier. E-order is implemented by the [Cap'n Proto](https://capnproto.org) distributed object-capability RPC protocol, which Cloudflare Workers uses for internal communications. -If an exception is thrown by a Durable Object stub all in-flight calls and future calls will fail with [exceptions](/durable-objects/observability/troubleshooting/). To continue invoking methods on a remote Durable Object instance a Worker must recreate the stub. There are no ordering guarantees between different stubs. +If an exception is thrown by a Durable Object stub all in-flight calls and future calls will fail with [exceptions](/durable-objects/observability/troubleshooting/). To continue invoking methods on a remote Durable Object a Worker must recreate the stub. There are no ordering guarantees between different stubs. diff --git a/src/content/docs/durable-objects/best-practices/create-durable-object-stubs-and-send-requests.mdx b/src/content/docs/durable-objects/best-practices/create-durable-object-stubs-and-send-requests.mdx index a933da8f3a0689f..271c8ba61030a3c 100644 --- a/src/content/docs/durable-objects/best-practices/create-durable-object-stubs-and-send-requests.mdx +++ b/src/content/docs/durable-objects/best-practices/create-durable-object-stubs-and-send-requests.mdx @@ -53,7 +53,7 @@ export default { // Every unique ID refers to an individual instance of the Durable Object class const id = env.MY_DURABLE_OBJECT.idFromName("foo"); - // A stub is a client used to invoke methods on the Durable Object instance + // A stub is a client used to invoke methods on the Durable Object const stub = env.MY_DURABLE_OBJECT.get(id); // Methods on the Durable Object are invoked via the stub @@ -90,7 +90,7 @@ export default { // Every unique ID refers to an individual instance of the Durable Object class const id = env.MY_DURABLE_OBJECT.idFromName("foo"); - // A stub is a client used to invoke methods on the Durable Object instance + // A stub is a client used to invoke methods on the Durable Object const stub = env.MY_DURABLE_OBJECT.get(id); // Methods on the Durable Object are invoked via the stub @@ -150,7 +150,7 @@ export default { // Every unique ID refers to an individual instance of the Durable Object class const id = env.MY_DURABLE_OBJECT.idFromName("foo"); - // A stub is a client used to invoke methods on the Durable Object instance + // A stub is a client used to invoke methods on the Durable Object const stub = env.MY_DURABLE_OBJECT.get(id); // Invoke the fetch handler on the Durable Object stub @@ -208,7 +208,7 @@ export default { // Every unique ID refers to an individual instance of the Durable Object class const id = env.MY_DURABLE_OBJECT.idFromName("foo"); - // A stub is a client used to invoke methods on the Durable Object instance + // A stub is a client used to invoke methods on the Durable Object const stub = env.MY_DURABLE_OBJECT.get(id); // Invoke the fetch handler on the Durable Object stub diff --git a/src/content/docs/durable-objects/get-started/walkthrough.mdx b/src/content/docs/durable-objects/get-started/walkthrough.mdx index feada4dea356241..def907d05d33d2b 100644 --- a/src/content/docs/durable-objects/get-started/walkthrough.mdx +++ b/src/content/docs/durable-objects/get-started/walkthrough.mdx @@ -10,7 +10,7 @@ import { Render, TabItem, Tabs, PackageManagers } from "~/components"; This guide will instruct you through: - Writing a Durable Object class. -- Writing a Worker which invokes methods on a Durable Object instance. +- Writing a Worker which invokes methods on a Durable Object. - Deploying a Durable Object. ## Prerequisites @@ -139,7 +139,7 @@ export default { // Every unique ID refers to an individual instance of the Durable Object class const id = env.MY_DURABLE_OBJECT.idFromName("foo"); - // A stub is a client used to invoke methods on the Durable Object instance + // A stub is a client used to invoke methods on the Durable Object const stub = env.MY_DURABLE_OBJECT.get(id); // Methods on the Durable Object are invoked via the stub @@ -159,7 +159,7 @@ export default { // Every unique ID refers to an individual instance of the Durable Object class const id = env.MY_DURABLE_OBJECT.idFromName("foo"); - // A stub is a client used to invoke methods on the Durable Object instance + // A stub is a client used to invoke methods on the Durable Object const stub = env.MY_DURABLE_OBJECT.get(id); // Methods on the Durable Object are invoked via the stub @@ -174,7 +174,7 @@ export default { ## 5. Configure Durable Object bindings -To allow a Worker to invoke methods on a Durable Object instance, the Worker must have a [Durable Object binding](/workers/runtime-apis/bindings/) in the project's [`wrangler.toml`](/workers/wrangler/configuration/#durable-objects) file. The binding is configured to use a particular Durable Object class. +To allow a Worker to invoke methods on a Durable Object, the Worker must have a [Durable Object binding](/workers/runtime-apis/bindings/) in the project's [`wrangler.toml`](/workers/wrangler/configuration/#durable-objects) file. The binding is configured to use a particular Durable Object class. ```toml [[durable_objects.bindings]] diff --git a/src/content/partials/durable-objects/example-rpc.mdx b/src/content/partials/durable-objects/example-rpc.mdx index a22506ec029d614..bc433e0a859ab07 100644 --- a/src/content/partials/durable-objects/example-rpc.mdx +++ b/src/content/partials/durable-objects/example-rpc.mdx @@ -26,7 +26,7 @@ export default { // Every unique ID refers to an individual instance of the Durable Object class const id = env.MY_DURABLE_OBJECT.idFromName("foo"); - // A stub is a client used to invoke methods on the Durable Object instance + // A stub is a client used to invoke methods on the Durable Object const stub = env.MY_DURABLE_OBJECT.get(id); // Methods on the Durable Object are invoked via the stub @@ -63,7 +63,7 @@ export default { // Every unique ID refers to an individual instance of the Durable Object class const id = env.MY_DURABLE_OBJECT.idFromName("foo"); - // A stub is a client used to invoke methods on the Durable Object instance + // A stub is a client used to invoke methods on the Durable Object const stub = env.MY_DURABLE_OBJECT.get(id); // Methods on the Durable Object are invoked via the stub From fe4bb115a6ef0e686a2a39b3f58111edfe87ff45 Mon Sep 17 00:00:00 2001 From: Jun Lee Date: Fri, 11 Oct 2024 16:50:51 +0100 Subject: [PATCH 10/10] Adding link in glossary to pricing page. --- src/content/glossary/durable-objects.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/glossary/durable-objects.yaml b/src/content/glossary/durable-objects.yaml index 1a32faf3c5df0d8..16cfbcf48250d79 100644 --- a/src/content/glossary/durable-objects.yaml +++ b/src/content/glossary/durable-objects.yaml @@ -66,4 +66,4 @@ entries: - term: "event context" general_definition: |- - The duration of time that a Durable Object is processing an event, such as a remote procedure call. Compute duration charges are incurred for the duration of the event context. \ No newline at end of file + The duration of time that a Durable Object is processing an event, such as a remote procedure call. [Compute duration charges](/durable-objects/platform/pricing) are incurred for the duration of the event context. \ No newline at end of file