← Cloudflare Durable Objects / durable-objects / reference
Экспорт классов Durable Object
exports поле в конфигурационный файл Wrangler это декларативный способ управления Durable Object class жизненный цикл. Вы объявляете каждый класс Durable Object, который экспортирует ваш Worker, указывая при этом, является ли он действующим (live), удалённым, переименованным или перенесённым, а Cloudflare сверяет ваше объявление с пространствами имён, уже выделенными для вашего Worker.
На этой странице рассказывается, как:
- Создание новый класс Durable Object.
- Удалить класс Durable Object и его данные.
- Переименовать класс Durable Object.
- Перенос класс Durable Object между Workers.
Как exports работает
Когда вы разворачиваете Worker, объявляющий exports, Cloudflare сравнивает три источника достоверных данных:
- Ваш код : набор классов Durable Object, которые Worker фактически экспортирует.
- Ваш
exportsконфигурация : то, что вы объявили для каждого класса. - Подготовленное состояние : пространства имён Durable Object, которые уже существуют для этого Worker.
Класс, который присутствует только в вашем коде, игнорируется, пока вы не объявите его в exports; Cloudflare не создаёт пространство имён неявно. Другие несоответствия, например действующая запись, класс которой отсутствует в коде, или созданное пространство имён без соответствующей записи, отображаются как структурированные ошибки либо, если намерение однозначно, как действия, которые Cloudflare выполняет за вас.
Минимальный exports блок объявляет каждый класс Durable Object как активную запись:
{
"durable_objects": {
"bindings": [
{
"name": "MY_DURABLE_OBJECT",
"class_name": "MyDurableObject",
},
],
},
"exports": {
"MyDurableObject": {
"type": "durable-object",
"storage": "sqlite",
},
},
}[[durable_objects.bindings]]
name = "MY_DURABLE_OBJECT"
class_name = "MyDurableObject"
[exports.MyDurableObject]
type = "durable-object"
storage = "sqlite"Чтобы объявить деструктивную операцию (удаление, переименование или перенос класса), измените в записи state в вариант tombstone. Имя класса остаётся прежним, а значение указывает Cloudflare, что делать с существующим namespace.
| Операция | state |
Обязательные поля |
|---|---|---|
| Определение нового класса (по умолчанию) | "created" (или опущено) |
storage |
| Удаление класса | "deleted" |
(нет) |
| Переименование класса | "renamed" |
renamed_to |
| Перенос класса в другой Worker | "transferred" |
transferred_to |
| Получение передачи от другого Worker | "expecting-transfer" |
storage, transfer_from |
Остальная часть этой страницы подробно описывает каждую операцию со ссылками на exports справочник по конфигурации с полной схемой.
Определение класса Durable Object
Чтобы определить новый класс Durable Object, добавьте запись в exports с ключом в виде имени класса и установите storage к "sqlite".
-
Добавьте класс в код Worker и экспортируйте его:
src/index.tsimport { DurableObject } from "cloudflare:workers"; export class MyDurableObject extends DurableObject { // ... } -
Добавьте привязку для класса (если вашему Worker нужен доступ к нему через
env) и объявить класс вexports:{ "durable_objects": { "bindings": [ { "name": "MY_DURABLE_OBJECT", "class_name": "MyDurableObject" } ] }, "exports": { "MyDurableObject": { "type": "durable-object", "storage": "sqlite" } } }[[durable_objects.bindings]] name = "MY_DURABLE_OBJECT" class_name = "MyDurableObject" [exports.MyDurableObject] type = "durable-object" storage = "sqlite" -
Разверните Worker:
npx wrangler deploy
Cloudflare выделяет пространство имён для класса при первом развёртывании. При последующих развёртываниях с той же записью изменений в пространстве имён не происходит: запись лишь подтверждает, что класс по-прежнему активен.
Удаление класса Durable Object
Замените действующую запись на deleted tombstone, чтобы вывести класс Durable Object из эксплуатации. Удаление класса удаляет его namespace и все свои сохраненные данные навсегда : это не мягкое удаление.
-
Удалите класс из кода Worker.
-
Удалите привязку класса из
durable_objects.bindings. -
Измените
exportsзапись для класса вdeletedtombstone:{ "exports": { "OldDurableObject": { "type": "durable-object", "state": "deleted" } } }[exports.OldDurableObject] type = "durable-object" state = "deleted" -
Разверните Worker:
npx wrangler deploy
A deleted tombstone имеет два предварительных условия, проверяемых при деплое:
- Класс не должен присутствовать в коде вашего Worker. Cloudflare не удалит пространство имён, класс которого всё ещё поставляется, поскольку привязки среды выполнения указывали бы на удалённое пространство имён.
- Ни один другой Worker в вашем аккаунте не может привязаться к этому namespace. Если другой Worker всё ещё привязан к классу, развёртывание отклоняется с
tombstone_delete_blocked_by_external_bindingsи возвращается список скриптов, которые на него ссылаются. Сначала повторно разверните эти Workers без привязки, а затем повторите развёртывание.
После удаления namespace его tombstone устаревает. Cloudflare сообщает об этом в результат сверки и выводит запись в removable_entries поэтому его можно безопасно удалить из exports.
Переименование класса Durable Object
При переименовании класса Durable Object сохранённые данные переносятся из одного класса в другой в пределах одного Worker. Для переименования необходимо:
- A
renamedtombstone, ключом для которого служит старое имя класса, сrenamed_toуказывающую на новое имя класса. - Действующая запись для нового имени класса в том же
exportsmap (чтобы данным было куда попасть).
Если это совершенно новое развёртывание и старого класса больше нет в вашем коде, достаточно одного развёртывания:
{
"exports": {
"OldName": {
"type": "durable-object",
"state": "renamed",
"renamed_to": "NewName"
},
"NewName": {
"type": "durable-object",
"storage": "sqlite"
}
}
}[exports.OldName]
type = "durable-object"
state = "renamed"
renamed_to = "NewName"
[exports.NewName]
type = "durable-object"
storage = "sqlite"После применения переименования имя класса пространства имён обновляется на NewName и привязки времени выполнения, ссылающиеся на новое имя класса, обращаются к тем же данным.
Избегайте простоя во время переименования
Переименование класса Durable Object включает два обновления, которые не полностью атомарны на уровне среды выполнения: указатель класса в пространстве имён и код Worker, экспортирующий этот класс. Во время развёртывания одно из обновлений может стать видимым раньше другого на несколько секунд. Чтобы избежать ошибок выполнения в этот период, используйте переименование в три развёртывания:
-
Создайте псевдоним, связывающий новое имя со старым классом. Добавьте новое имя класса в код как каноническое, а затем повторно экспортируйте его под старым именем, чтобы существующие экземпляры продолжали корректно разрешаться:
src/index.tsimport { DurableObject } from "cloudflare:workers"; export class NewName extends DurableObject { // ... } export { NewName as OldName };Оставьте
exportsбез изменений. Разверните. -
Примените переименование, пока псевдоним ещё действует. Обновите
exportsчтобы добавитьrenamedtombstone и новой активной записью:{ "exports": { "OldName": { "type": "durable-object", "state": "renamed", "renamed_to": "NewName" }, "NewName": { "type": "durable-object", "storage": "sqlite" } } }[exports.OldName] type = "durable-object" state = "renamed" renamed_to = "NewName" [exports.NewName] type = "durable-object" storage = "sqlite"Разверните. Cloudflare применяет переименование и выводит
tombstone_class_still_in_codeинформационное уведомление: это ожидаемое поведение, подтверждающее безопасный шаблон развёртывания. -
Удалите псевдоним. После того как предыдущее развёртывание полностью завершится, удалите
OldNameпсевдоним из вашего кода:src/index.tsimport { DurableObject } from "cloudflare:workers"; export class NewName extends DurableObject { // ... }Оставьте
exportsбез изменений. Разверните.OldNametombstone теперь устарел, и Cloudflare отображает его вremovable_entries: вы можете удалить запись изexportsпри следующем изменении конфигурации.
renamed_to целевой объект должен:
- Должен быть допустимым идентификатором JavaScript и отличаться от имени исходного класса.
- Отображается как активная запись (
state: "created"или опущен) в том жеexportsmap. Cloudflare отклоняетrenamed_toзначение, которое указывает на другой tombstone, либо отсутствует полностью. - Не конфликтовать с уже существующим namespace с таким же именем в этом Worker. Если namespace с целевым именем уже существует, удалите его через собственный
deletedtombstone в одном из предыдущих деплоев.
Перенос класса Durable Object между Workers
Перенос перемещает существующее пространство имён Durable Object с одного Worker (исходного источник) другому Worker (в цель) в одном аккаунте. Поскольку два Worker должны координироваться между собой, перенос выполняется в несколько этапов деплоя.
Worker-получатель объявляет expecting-transfer запись, указывающую исходный Worker. Исходный Worker объявляет transferred tombstone, указывающий целевой Worker. Фактическая передача фиксируется, когда происходит деплой исходного Worker.
Рекомендуемая последовательность состоит из четырёх развёртываний:
-
Source Worker: исходное состояние. Источник объявляет
MyDOкак активный класс. Больше пока ничего не изменилось.{ "exports": { "MyDO": { "type": "durable-object", "storage": "sqlite" } } }[exports.MyDO] type = "durable-object" storage = "sqlite" -
Целевой Worker: получите перенос. Целевой объект добавляет
MyDOк своему коду и объявляетexpecting-transferзапись, указывающую исходный Worker. Не не добавьтеdurable_objects.bindingsзапись дляMyDOна целевом объекте. Cloudflare пока не маршрутизирует самоссылающиеся привязки через пространство имён источника на этом этапе.{ "exports": { "MyDO": { "type": "durable-object", "state": "expecting-transfer", "storage": "sqlite", "transfer_from": "source-worker" } } }[exports.MyDO] type = "durable-object" state = "expecting-transfer" storage = "sqlite" transfer_from = "source-worker"Разверните целевой Worker. Cloudflare регистрирует ожидающую передачу и создаёт
Transfer pendingуведомление в результат сверки. -
Source Worker: фиксация передачи. Измените у источника значение
MyDOзапись вtransferredtombstone, указывающий целевой Worker. Пока оставьте класс в исходном коде:{ "exports": { "MyDO": { "type": "durable-object", "state": "transferred", "transferred_to": "target-worker" } } }[exports.MyDO] type = "durable-object" state = "transferred" transferred_to = "target-worker"Разверните исходный Worker. Cloudflare сопоставляет ожидающую передачу и атомарно переназначает пространство имён целевому Worker. В результатах сверки указывается
Transferred (committed): MyDO → target-worker.Если исходному Worker всё ещё требуется доступ к
MyDOпосле фиксации переноса обновите егоdurable_objects.bindingsзапись, указывающую на целевой Worker сscript_name:{ "durable_objects": { "bindings": [ { "name": "MY_DURABLE_OBJECT", "class_name": "MyDO", "script_name": "target-worker" } ] } }[[durable_objects.bindings]] name = "MY_DURABLE_OBJECT" class_name = "MyDO" script_name = "target-worker"Если исходному Worker больше не требуется доступ к
MyDO, удалите binding при удаленииMyDOиз кода исходного Worker. -
Целевой Worker: привяжите класс. После того как развёртывание источника полностью завершится, повторно разверните целевой объект с
durable_objects.bindingsзапись дляMyDO. Теперь привязка указывает на пространство имён целевого Worker.{ "durable_objects": { "bindings": [ { "name": "MY_DURABLE_OBJECT", "class_name": "MyDO" } ] }, "exports": { "MyDO": { "type": "durable-object", "storage": "sqlite" } } }[[durable_objects.bindings]] name = "MY_DURABLE_OBJECT" class_name = "MyDO" [exports.MyDO] type = "durable-object" storage = "sqlite"
После того как handoff будет развёрнут повсеместно, вы можете удалить MyDO из кода исходного Worker и удалите transferred tombstone из конфигурации исходного Worker exports map. Пока другие Workers в аккаунте всё ещё привязаны к MyDO на источнике, вывод сверки перечисляет их в referencing_scripts; разверните каждый из них заново, перенаправив привязки на целевой объект, прежде чем удалять исходный tombstone.
Отмена ожидающего переноса
Ожидающий перенос сохраняется, пока исходный Worker не подтвердит его с помощью transferred tombstone, либо целевой Worker отменяет операцию, удалив expecting-transfer запись. Чтобы отменить перенос, разверните целевой объект заново без этой записи (или замените её обычной активной записью). Cloudflare удалит отложенную запись, и исходный Worker сохранит своё пространство имён.
Ограничения переноса
- Оба Worker должны находиться в одном аккаунте Cloudflare.
- Кросс-dispatch-namespace transfers не поддерживаются. Исходный и целевой Worker должны находиться в одном контексте dispatch namespace (либо оба вне dispatch namespace).
- Целевой Worker может одновременно хранить только одну ожидающую подсказку фазы 1 для класса. Чтобы перенаправить ожидающий перенос на другой источник, сначала отмените текущий ожидающий перенос.
Бэкенды хранилища
Активные записи (state: "created" и state: "expecting-transfer") должен объявить storage значение:
"sqlite"выбирает бэкенд хранения SQLite. Это рекомендуемый и единственный вариант для новых пространств имён. Пространства имён на основе SQLite поддерживают SQL, Point-in-Time Recovery, и более высокий лимит хранилища на объект."legacy-kv"выбирает бэкенд хранения ключ-значение. Cloudflare принимает это значение только для пространств имён, уже созданных с хранилищем ключ-значение (как правило, для Workers, начинавших работу на устаревшаяmigrationsмассив до того как SQLite стал бэкендом по умолчанию). Вы не можете создать новое пространство имён на основе key-value-хранилища черезexports.
Тип хранилища неизменяем после создания пространства имён. Cloudflare отклоняет exports изменение, которое переключает выделенное пространство имён с sqlite к legacy-kv или наоборот, с ошибкой storage_type_mismatch. Чтобы действительно сменить бэкенд хранилища, удалите пространство имён через deleted tombstone и заново подготовить его с новым бэкендом (с полной потерей данных в процессе).
Чтение результатов сверки
Когда развёртывание применяет изменение жизненного цикла класса Durable Object, wrangler deploy выводит Durable Object exports reconciliation блок. Этот блок также появляется, если в результате сверки возникают предупреждения, информационные уведомления или записи, которые можно удалить. Wrangler не выводит блок, если ничего не изменилось и уведомлений нет.
Типичный вывод выглядит следующим образом:
Durable Object exports reconciliation:
Created: ChatRoom
Renamed: OldRoom → ChatRoom
Transferred (committed): Widget → target-worker
Transfer pending: Incoming ← source-worker
Info:
[tombstone_class_still_in_code] OldRoom: Tombstone of type 'renamed' applied. Class 'OldRoom' is still exported in code; this is the supported pattern for zero-downtime rename rollouts.
[stale_tombstone] OldGone: Tombstone of type 'deleted' for class 'OldGone' has no effect (no namespace exists with this class name). Safe to remove from `exports`.
Safe to remove from `exports`: OldGoneБлок состоит из четырёх разделов:
- Линии действий (
Created,Updated,Deleted,Renamed,Transferred,Transfer pending) сообщают об изменениях, которые Cloudflare применил в ходе этого деплоя. - Предупреждения (жёлтым) отмечаются условия, которые стоит проверить, но которые не блокируют развёртывание. Набор предупреждающих сценариев зарезервирован на будущее: текущие развёртывания Cloudflare их не выдают.
- Информация (приглушённым цветом) отображаются некритичные уведомления: устаревшие tombstone, которые больше не действуют, и tombstone, применённые, пока исходный класс всё ещё присутствует в коде (поддерживаемый способ развёртывания без простоя).
- Можно безопасно удалить из
exportsперечисляет устаревшие записи tombstone, к исходному классу которых не привязан ни один другой Worker в аккаунте. Вы можете удалить эти записи изexportsmap при следующем изменении конфигурации.
Записи с пометкой «Информация» могут включать referencing_scripts список: другие Workers в аккаунте, чьи привязки по-прежнему указывают на затронутое пространство имён. Прежде чем удалять запись tombstone, повторно разверните эти Workers, перенаправив привязки на новое имя класса, иначе их привязки останутся без класса.
Если развёртывание завершается ошибкой, в выводе отображается структурированная ошибка по каждому классу:
✘ [orphaned_provisioned_namespace] class 'Bar': A namespace exists for 'Bar' but no `exports` entry declares it.
Suggestion: add an `exports` entry for 'Bar', or add a `deleted` tombstone to remove the namespace.
Referencing scripts: worker-foo, worker-barВсе ошибки уровня класса из одного развёртывания сообщаются вместе, чтобы вы могли исправить их за один проход. См. справочник по ошибкам с полным списком сценариев ошибок.
Устаревшие маркеры удаления и их очистка
Tombstone становится stale когда его применение не приводит к изменению состояния, например deleted tombstone для класса, чей namespace уже удалён, либо renamed tombstone после того, как переименование уже применено.
Cloudflare выдаёт stale_tombstone информационное уведомление при каждом развёртывании, где запись tombstone устарела, пока вы не удалите эту запись из exports. Это уведомление намеренно повторяется, чтобы вы не забыли выполнить очистку.
Для переименованных и перенесённых записей-заглушек (tombstone) Cloudflare также перечисляет другие Workers в вашем аккаунте, чьи durable_objects.bindings записи по-прежнему ссылаются на имя исходного класса. Они отображаются как referencing_scripts в информационном уведомлении. Пока referencing_scripts не пуст, удаление записи tombstone может оставить эти привязки без класса: сначала повторно разверните ссылающиеся Workers, перенаправив привязки на новый класс.
Верхнеуровневый флаг «Safe to remove from exports" строка в выводе сверки указывает на каждый устаревший tombstone, у которого referencing_scripts пуст. Используйте этот список как достоверную подсказку «эти записи уже можно удалить».
Окружения, dispatch namespaces и предпросмотры
exports можно указать на верхнем уровне конфигурационного файла Wrangler и переопределить для каждого окружение:
{
// top-level exports apply to the default environment
"exports": {
"MyDO": { "type": "durable-object", "storage": "sqlite" }
},
"env": {
"staging": {
// override for the staging environment
"exports": {
"MyDO": { "type": "durable-object", "storage": "sqlite" }
}
}
}
}[exports.MyDO]
type = "durable-object"
storage = "sqlite"
[env.staging.exports.MyDO]
type = "durable-object"
storage = "sqlite"Если exports объявлен только на верхнем уровне, именованные окружения наследуют то же значение. Каждое окружение хранит собственные выделенные пространства имён, поэтому записи tombstone применяются только в том окружении, где они объявлены.
Превью-деплои и dispatch namespaces подчиняются тем же правилам. Перенос между разными dispatch namespace не поддерживается: исходный и целевой Worker в transferred / expecting-transfer должны находиться в одном и том же контексте dispatch-namespace (или оба быть вне какого-либо dispatch namespace).
exports справочник по конфигурации
exports поле представляет собой map, ключами которой служат имена классов Durable Object. Каждое значение представляет собой объект, поля которого зависят от state:
-
typestringобязательно- Для записей классов Durable Object укажите значение
"durable-object".
- Для записей классов Durable Object укажите значение
-
statestringнеобязательно- Состояние жизненного цикла. Одно из
"created"(значение по умолчанию, для использования можно не указывать),"deleted","renamed","transferred", или"expecting-transfer".
- Состояние жизненного цикла. Одно из
-
storagestringусловный- Обязательно, если
stateэто"created"или"expecting-transfer". Один из"sqlite"(рекомендуется, единственное допустимое значение для новых пространств имён) или"legacy-kv"(только для существующих пространств имён на основе key-value). Запрещено для состояний tombstone.
- Обязательно, если
-
renamed_tostringусловный- Обязательно, если
stateэто"renamed". Имя класса назначения. Должно быть допустимым идентификатором JavaScript, отличаться от имени исходного класса и присутствовать в виде активной записи в том жеexportsmap.
- Обязательно, если
-
transferred_tostringусловный- Обязательно, если
stateэто"transferred". Имя целевого Worker, который получит пространство имён.
- Обязательно, если
-
transfer_fromstringусловный- Обязательно, если
stateэто"expecting-transfer". Имя исходного Worker, из которого переносится пространство имён.
- Обязательно, если
В следующей таблице перечислены разрешённые и запрещённые поля для каждого state:
state |
Обязательный | Forbidden |
|---|---|---|
"created" (по умолчанию) |
storage |
renamed_to, transferred_to, transfer_from |
"deleted" |
(нет) | storage, renamed_to, transferred_to, transfer_from |
"renamed" |
renamed_to |
storage, transferred_to, transfer_from |
"transferred" |
transferred_to |
storage, renamed_to, transfer_from |
"expecting-transfer" |
storage, transfer_from |
renamed_to, transferred_to |
Справочник по ошибкам
Если развёртывание не проходит проверку согласованности, Cloudflare возвращает по одной ошибке на класс вместе со структурированным scenario тег, понятное человеку сообщение и, где применимо, suggestion и referencing_scripts список:
| Сценарий | Значение | Как исправить |
|---|---|---|
provisioned_class_missing_from_config |
Пространство имён существует для класса, который код Worker всё ещё экспортирует, но exports не содержит записи для него. |
Добавьте активную запись (state: "created") чтобы оставить пространство имён, или добавить tombstone (deleted, renamed, или transferred) чтобы вывести его из эксплуатации. |
config_export_not_in_code |
Действующая запись объявляет класс, который код Worker не экспортирует. | Добавьте класс обратно в код или замените запись на tombstone. |
config_references_nonexistent_class |
Действующая запись объявляет класс, которого нет ни в коде, ни среди созданных. | Удалите запись либо добавьте класс в код Worker. |
orphaned_provisioned_namespace |
Пространство имён существует для класса, которого нет ни в коде, ни в объявлениях. | Добавьте tombstone для класса или верните класс обратно в код и exports. |
invalid_export |
Одна exports запись структурно некорректна: например, если запрашивается legacy-kv для нового пространства имён, либо класс, который сопоставлен более чем с одним выделенным пространством имён. |
Исправьте запись: используйте "storage": "sqlite" для новых пространств имён, либо устраните дублирование с помощью deleted или renamed tombstone. |
tombstone_delete_class_still_in_code |
A deleted tombstone указывает класс, который всё ещё экспортируется в коде. |
Сначала удалите класс из кода, а затем разверните tombstone. |
tombstone_delete_blocked_by_external_bindings |
Ещё один Worker в аккаунте привязан к удаляемому пространству имён. | Разверните заново ссылающиеся Workers без этой привязки, а затем повторите развёртывание. |
tombstone_renamed_to_occupied |
A renamed_to целевой объект конфликтует с уже существующим пространством имён с таким же именем. |
Удалите конфликтующее пространство имён через его собственный deleted tombstone в предыдущем деплое. |
transferred_pending_not_found |
A transferred tombstone не имеет соответствующего expecting-transfer запись в целевом объекте. |
Сначала разверните целевой Worker с expecting-transfer запись, указывающую этот Worker. |
transferred_target_missing |
Worker-получатель, указанный в transferred_to больше не существует. |
Обновите transferred_to к допустимой цели, либо удалите tombstone. |
transferred_target_mismatch |
transferred_to значение не совпадает с целевым объектом, записанным в ожидающем transfer. |
Задайте transferred_to целевому объекту ожидающего transfer, либо позволить целевому объекту отменить его expecting-transfer запись перед перенаправлением. |
transferred_source_in_dispatch_namespace |
Worker-источник, объявляющий transferred tombstone находится в dispatch namespace; перенос между разными dispatch namespace не поддерживается. |
Выполните передачу в пределах одного контекста dispatch-namespace. |
transferred_target_in_dispatch_namespace |
Получатель transferred tombstone находится в dispatch namespace; перенос между разными dispatch namespace не поддерживается. |
Отмените ожидающий перенос, повторно развернув целевой Worker без expecting-transfer, или сохранить оба Worker в одном контексте. |
phase_one_transfer_after_commit_mismatch |
Пространство имён получателя было перенесено не из того источника, который указан. | Удалите expecting-transfer запись: перенос нельзя перенаправить после фиксации. |
phase_one_transfer_target_class_provisioned |
У Worker-получателя уже есть пространство имён для этого класса. | Замените expecting-transfer запись обычной активной записью либо сначала удалите существующее пространство имён. |
phase_one_transfer_duplicate |
Ещё один expecting-transfer hint уже выполняется для этого же класса. |
Сначала отмените существующий ожидающий перенос, удалив или заменив соответствующую запись. |
phase_one_transfer_source_missing |
Worker-источник, указанный в transfer_from не существует в аккаунте. |
Исправьте имя исходного Worker. |
phase_one_transfer_source_namespace_missing |
У Worker-источника нет пространства имён для этого класса. | Убедитесь, что класс развёрнут в исходном Worker, прежде чем целевой объявит expecting-transfer. |
phase_one_transfer_source_in_dispatch_namespace |
Worker-источник находится в пространстве имён диспетчеризации: перенос между пространствами диспетчеризации не поддерживается. | Переместите передачу в пределах одного контекста dispatch-namespace. |
phase_one_transfer_target_in_dispatch_namespace |
Worker-получатель находится в пространстве имён диспетчеризации: перенос между пространствами диспетчеризации не поддерживается. | Переместите передачу в пределах одного контекста dispatch-namespace. |
storage_type_mismatch |
Объявленный storage значение не совпадает с бэкендом хранилища подготовленного namespace. |
Бэкенды хранилища нельзя изменить на месте. Если действительно необходимо переключиться, удалите пространство имён и создайте его заново с новым бэкендом. |
free_tier_requires_sqlite |
Тарифный план аккаунта поддерживает только пространства имён на основе SQLite, но запись запрашивает legacy-kv. |
Используйте "storage": "sqlite". |
Ограничения и лимиты
exportsиmigrationsявляются взаимоисключающими. Конфигурация Worker, содержащая оба поля, отклоняется при валидации. После того как Worker развёрнут сexports, последующие развёртывания должны продолжать использоватьexports(или ни то, ни другое, что приводит к сверке с пустой конфигурацией и обычно является ошибкой).wrangler versions uploadне применяет изменения жизненного цикла. Как и в случае с устаревшимmigrationsмассив, изменения жизненного цикла Durable Object можно применить только черезwrangler deploy. Если ваша конфигурация Wrangler содержитexportsзаписи,wrangler versions uploadсразу завершается с понятной ошибкой, по которой можно принять меры. См. Управление развёртыванием: миграции Durable Object.- Gradual Deployments не поддерживаются вместе с
exports. Изменения жизненного цикла атомарны на уровне управляющей плоскости Cloudflare и не могут применяться постепенно. См. Gradual Deployments с Durable Objects: изменения жизненного цикла класса Durable Object. - Откат нельзя выполнить через изменение жизненного цикла. Вы не можете откатиться к версии, развёрнутой до
exports-управляемое изменение жизненного цикла. См. Откаты: привязки. - Бэкенды хранилища неизменяемы после выделения. Вы не можете изменить у пространства имён
storageзначение на месте; вместо этого удалите и подготовьте заново.
Мигрировать с устаревшего migrations поток
Существующие Workers, использующие migrations массив может перейти в exports без миграции данных. Созданные пространства имён остаются на месте, меняется только структура конфигурации.
Чтобы определить текущий бэкенд хранилища класса, найдите миграцию, которая изначально его создала. Классы, добавленные через new_sqlite_classes используйте sqlite, тогда как классы, добавленные через new_classes используйте legacy-kv.
- Определите активные классы Durable Object, которые сейчас экспортирует ваш Worker. Каждый класс с активным пространством имён становится действующим
exportsзапись. - Замените
migrationsмассив сexportsmap. Для каждого существующего класса добавьте запись с ключом в виде имени класса и"type": "durable-object". Сопоставьте существующий бэкенд хранилища с"storage": "sqlite"или"storage": "legacy-kv". - Удалите
migrationsмассив из вашей конфигурации. - Разверните.
Для сравнения, эквивалент типичного migrations история выглядит так:
{
"migrations": [
{ "tag": "v1", "new_sqlite_classes": ["ChatRoom"] }
]
}[[migrations]]
tag = "v1"
new_sqlite_classes = [ "ChatRoom" ]{
"exports": {
"ChatRoom": { "type": "durable-object", "storage": "sqlite" }
}
}[exports.ChatRoom]
type = "durable-object"
storage = "sqlite"Дальнейшие изменения жизненного цикла (удаление, переименование, перенос) выполняются исключительно через exports : не существует эквивалента tag поле, и нет необходимости хранить исторические записи. Текущее состояние вашего exports map является источником достоверных данных.