INTEGRITY Dokumentace

Exporty tříd Durable Object

exports pole ve vašem Konfigurační soubor Wrangler je deklarativní způsob správy Třída Durable Object životní cyklus. Pro každou třídu Durable Object, kterou váš Worker exportuje, deklarujete, zda je aktivní, smazaná, přejmenovaná nebo přenesená, a Cloudflare tuto deklaraci porovná s namespace, které už byly pro váš Worker zřízeny.

Tato stránka popisuje, jak:

Jak exports funguje

Když nasadíte Worker, který deklaruje exports, Cloudflare porovnává tři zdroje pravdy:

  1. Váš kód, sadu tříd Durable Object, které Worker skutečně exportuje.
  2. Váš exports konfigurace, co jste deklarovali o každé třídě.
  3. Přidělený stav, jmenné prostory Durable Object, které pro tohoto Workera již existují.

Třída, která se vyskytuje pouze ve vašem kódu, se ignoruje, dokud ji nedeklarujete v exports; Cloudflare namespace implicitně nezřizuje. Ostatní nesrovnalosti, jako aktivní položka, jejíž třída v kódu chybí, nebo zřízený namespace bez odpovídající položky, se zobrazí jako strukturované chyby, případně, je-li záměr jednoznačný, jako akce, které Cloudflare provede za vás.

Minimální exports blok deklaruje každou třídu Durable Object jako živý záznam:

{
	"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"

Chcete-li deklarovat destruktivní operaci, tedy smazání, přejmenování nebo přenos třídy, změňte u dané položky state na variantu tombstone. Název třídy zůstane stejný, hodnota určuje, co má Cloudflare s existujícím jmenným prostorem udělat.

Operace state Povinná pole
Definice nové třídy (výchozí) "created" (nebo vynecháno) storage
Odstranění třídy "deleted" (žádné)
Přejmenování třídy "renamed" renamed_to
Přenos třídy do jiného Workeru "transferred" transferred_to
Přijetí přenosu z jiného Workeru "expecting-transfer" storage, transfer_from

Zbytek této stránky podrobně popisuje jednotlivé operace a odkazuje na exports konfigurační reference kde najdete úplné schéma.

Definice třídy Durable Object

Chcete-li definovat novou třídu Durable Object, přidejte položku do exports podle názvu třídy a nastavte storage na "sqlite".

  1. Přidejte třídu do kódu Workeru a exportujte ji:

    src/index.ts
    import { DurableObject } from "cloudflare:workers";
    
    export class MyDurableObject extends DurableObject {
      // ...
    }
  2. Přidejte binding pro třídu (pokud k ní váš Worker potřebuje přistupovat přes env) a deklarujte třídu v 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"
  3. Nasaďte Worker:

    npx wrangler deploy

Cloudflare při prvním nasazení vytvoří pro danou třídu jmenný prostor. Při dalších nasazeních se stejným záznamem se ve jmenném prostoru nic nemění, záznam pouze potvrzuje, že třída je stále aktivní.

Odstranění třídy Durable Object

Nahraďte aktivní záznam za deleted tombstone pro ukončení třídy Durable Object. Odstranění třídy odebere její jmenný prostor a všechna svá uložená data natrvalo, nejde o měkké mazání.

  1. Odstraňte třídu z kódu Workeru.

  2. Odstraňte binding pro danou třídu z durable_objects.bindings.

  3. Změňte exports položku pro třídu na deleted tombstone:

    {
      "exports": {
        "OldDurableObject": {
          "type": "durable-object",
          "state": "deleted"
        }
      }
    }
    [exports.OldDurableObject]
    type = "durable-object"
    state = "deleted"
  4. Nasaďte Worker:

    npx wrangler deploy

A deleted tombstone má dvě podmínky vynucené v době nasazení:

Jakmile je namespace smazán, tombstone zastará. Cloudflare to hlásí v výstup sesouhlasení a uvede záznam v removable_entries takže jej můžete bezpečně odebrat z exports.

Přejmenování třídy Durable Object

Přejmenování třídy Durable Object přesune uložená data z jedné třídy do druhé v rámci stejného Workeru. Přejmenování vyžaduje:

Pokud jde o zcela nové nasazení, kde už stará třída ve vašem kódu není, stačí jediné nasazení:

{
	"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"

Po provedení přejmenování se název třídy namespace aktualizuje na NewName a runtime vazby odkazující na nový název třídy se přeloží na stejná data.

Jak se vyhnout výpadku během přejmenování

Přejmenování třídy Durable Object zahrnuje dvě aktualizace, které nejsou na úrovni běhového prostředí dokonale atomické: ukazatel třídy v namespace a kód Workeru, který danou třídu exportuje. Během postupného nasazení se jedna aktualizace může na pár sekund projevit dříve než druhá. Aby v tomto okně nedocházelo k chybám za běhu, použijte přejmenování ve třech nasazeních:

  1. Vytvořte alias nového názvu na starou třídu. Přidejte nový název třídy do svého kódu jako kanonickou třídu a znovu ji exportujte pod starým názvem, aby se stávající instance i nadále správně přiřazovaly:

    src/index.ts
    import { DurableObject } from "cloudflare:workers";
    
    export class NewName extends DurableObject {
      // ...
    }
    export { NewName as OldName };

    Ponechte exports beze změny. Nasaďte.

  2. Proveďte přejmenování, dokud je alias stále v platnosti. Aktualizujte exports přidat renamed tombstone a novým aktivním záznamem:

    {
      "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"

    Nasaďte. Cloudflare provede přejmenování a zobrazí tombstone_class_still_in_code informační upozornění: to je očekávané chování a potvrzuje bezpečný postup nasazení.

  3. Odstraňte alias. Jakmile se předchozí nasazení plně dokončí, odeberte OldName alias z vašeho kódu:

    src/index.ts
    import { DurableObject } from "cloudflare:workers";
    
    export class NewName extends DurableObject {
      // ...
    }

    Ponechte exports beze změny. Nasaďte. OldName tombstone je nyní neaktuální a Cloudflare ho uvádí v removable_entries, můžete položku odstranit z exports při příští úpravě konfigurace.

renamed_to cíl musí:

Přenos třídy Durable Object mezi Workery

Přenos přesouvá existující namespace Durable Object z jednoho Workeru (zdrojového zdroj) do jiného Workeru (cíl) ve stejném účtu. Protože musí spolupracovat dva Workers, probíhá převod ve více nasazeních.

Cílový Worker deklaruje expecting-transfer položku, která pojmenovává zdrojový Worker. Zdrojový Worker deklaruje transferred tombstone, který pojmenovává cílový Worker. Ke skutečnému předání dojde ve chvíli, kdy proběhne nasazení zdrojového Workeru.

Doporučený postup se skládá ze čtyř nasazení:

  1. Zdrojový Worker: počáteční stav. Zdroj deklaruje MyDO jako živou třídu. Nic dalšího se zatím nezměnilo.

    {
      "exports": {
        "MyDO": { "type": "durable-object", "storage": "sqlite" }
      }
    }
    [exports.MyDO]
    type = "durable-object"
    storage = "sqlite"
  2. Cílový Worker: přijměte přenos. Cíl přidává MyDO ke svému kódu a deklaruje expecting-transfer položku pojmenovávající zdrojový Worker. Ne ne přidejte durable_objects.bindings položka pro MyDO na cíli. Cloudflare v této fázi nesměruje vazby odkazující samy na sebe přes namespace zdroje.

    {
      "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"

    Nasaďte cíl. Cloudflare zaznamená čekající přenos a vygeneruje Transfer pending upozornění v výstup sesouhlasení.

  3. Zdrojový Worker: potvrzení přenosu. Změňte u zdroje MyDO položku na transferred tombstone, který pojmenovává cílový Worker. Třídu prozatím ponechte ve zdrojovém kódu:

    {
      "exports": {
        "MyDO": {
          "type": "durable-object",
          "state": "transferred",
          "transferred_to": "target-worker"
        }
      }
    }
    [exports.MyDO]
    type = "durable-object"
    state = "transferred"
    transferred_to = "target-worker"

    Nasaďte zdroj. Cloudflare spáruje čekající přenos a atomicky přiřadí namespace cílovému Workeru. Výstup sesouhlasení uvádí Transferred (committed): MyDO → target-worker.

    Pokud zdrojový Worker stále potřebuje přístup k MyDO po potvrzení přenosu aktualizujte jeho durable_objects.bindings položku tak, aby ukazovala na cílový Worker s 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"

    Pokud zdrojový Worker již nepotřebuje přístup k MyDO, vazbu odeberte, když odeberete MyDO ze zdrojového kódu Workeru.

  4. Cílový Worker: navažte třídu. Jakmile se nasazení zdroje plně dokončí, znovu nasaďte cíl s durable_objects.bindings položka pro MyDO. Binding se nyní přeloží na namespace na cílovém Workeru.

    {
      "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"

Jakmile se předání rozšíří všude, můžete odebrat MyDO ze zdrojového kódu Workeru a odstraňte transferred tombstone ze zdrojového exports mapu. Dokud jsou na ni v účtu ještě navázány jiné Workery přes MyDO na zdroji, výstup sesouhlasení je uvádí v referencing_scripts; před odstraněním zdrojového tombstonu je všechny znovu nasaďte s vazbami přesměrovanými na cíl.

Zrušte čekající přenos

Čekající přesun trvá, dokud zdrojový Worker nepotvrdí akci pomocí transferred tombstone, nebo cílový Worker zruší akci odebráním expecting-transfer položku. Pro zrušení nasaďte cíl znovu bez této položky (nebo ji nahraďte běžnou aktivní položkou). Cloudflare smaže čekající záznam a zdrojový Worker si ponechá svůj namespace.

Omezení přenosu

Backendy úložiště

Živé záznamy (state: "created" a state: "expecting-transfer") musí deklarovat storage hodnotu:

Typ úložiště je po vytvoření namespace neměnný. Cloudflare odmítne exports změna, která přepne zřízený namespace z sqlite na legacy-kv nebo naopak, s chybou storage_type_mismatch. Chcete-li úložný backend skutečně změnit, odstraňte namespace pomocí deleted tombstone a znovu ho zřiďte pod novým backendem (s úplnou ztrátou dat mezi tím).

Čtení výstupu sesouhlasení

Když nasazení provede změnu životního cyklu třídy Durable Object, wrangler deploy vypíše Durable Object exports reconciliation blok. Blok se zobrazí i tehdy, pokud sesouhlasení vygeneruje varování, informační upozornění nebo odstranitelné záznamy. Wrangler blok vynechá, pokud se nic nezměnilo a nejsou žádná upozornění.

Typický výstup vypadá takto:

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

Blok má čtyři sekce:

Záznamy typu Info mohou obsahovat referencing_scripts seznamu: další Workery v účtu, jejichž bindingy stále směřují na dotčený namespace. Než tombstone odstraníte, znovu nasaďte tyto Workery s bindingy přesměrovanými na nový název třídy, jinak jejich bindingy osiří.

Pokud nasazení selže, výstup zobrazí strukturovanou chybu pro každou třídu:

✘ [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

Všechny chyby na úrovni tříd z jednoho nasazení se hlásí společně, takže je můžete opravit na jeden zátah. Více informací najdete v přehled chyb kde najdete úplný seznam chybových scénářů.

Neaktuální tombstony a jejich čištění

Tombstone se stane stale pokud jeho aplikace nevyvolá žádnou změnu stavu, například deleted tombstone pro třídu, jejíž jmenný prostor již byl odstraněn, nebo renamed tombstone poté, co přejmenování již proběhlo.

Cloudflare vygeneruje stale_tombstone informační upozornění při každém nasazení, kde je tombstone zastaralý, dokud danou položku neodstraníte z exports. Toto upozornění se záměrně opakuje, abyste nezapomněli provést úklid.

U přejmenovaných a přesunutých tombstones Cloudflare také vypíše ostatní Workery ve vašem účtu, jejichž durable_objects.bindings položky stále odkazují na název zdrojové třídy. Ty se zobrazují jako referencing_scripts v informačním upozornění. Zatímco referencing_scripts není prázdný, odstranění tombstonu by mohlo tyto bindingy osiřit. Nejprve znovu nasaďte odkazující Workery s bindingy přesměrovanými na novou třídu.

Nejvyšší úroveň "Lze bezpečně odstranit z exports" řádek ve výstupu sesouhlasení pojmenovává každý zastaralý tombstone, jehož referencing_scripts je prázdný. Tento seznam berte jako závazné vodítko „tyto položky teď můžete smazat“.

Prostředí, dispatch namespaces a náhledy

exports lze zadat na nejvyšší úrovni konfiguračního souboru Wrangler a přepsat pro každou prostředí:

{
	// 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"

Pokud exports je deklarován pouze na nejvyšší úrovni, pojmenovaná prostředí přebírají stejnou hodnotu. Každé prostředí si udržuje vlastní zřízené namespace, takže tombstony platí pouze v prostředí, ve kterém jsou deklarovány.

Náhledová nasazení a dispatch namespaces se řídí stejnými pravidly. Přenosy mezi různými dispatch namespace nejsou podporované, zdrojový a cílový Worker v transferred / expecting-transfer musí obě žít ve stejném kontextu dispatch namespace (nebo obě mimo jakýkoli dispatch namespace).

exports konfigurační reference

exports pole je mapa klíčovaná podle názvu třídy Durable Object. Každá hodnota je objekt, jehož pole závisí na state:

Následující tabulka uvádí povolená a zakázaná pole pro každý state:

state Povinné Forbidden
"created" (výchozí) storage renamed_to, transferred_to, transfer_from
"deleted" (žádné) 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

Přehled chyb

Pokud nasazení selže při reconciliation, Cloudflare vrátí jednu chybu za každou třídu spolu se strukturovaným scenario tag, čitelnou zprávu a případně suggestion a referencing_scripts seznamu:

Scénář Význam Jak to opravit
provisioned_class_missing_from_config Namespace existuje pro třídu, kterou kód Workeru stále exportuje, ale exports pro to nemá žádnou položku. Přidejte živou položku (state: "created") pro zachování jmenného prostoru, nebo přidejte tombstone (deleted, renamed, nebo transferred) pro jeho vyřazení.
config_export_not_in_code Aktivní položka deklaruje třídu, kterou kód Workeru neexportuje. Přidejte třídu do kódu, nebo záznam nahraďte tombstone.
config_references_nonexistent_class Aktivní položka deklaruje třídu, která není ani v kódu, ani zřízená. Odstraňte záznam, nebo přidejte třídu do kódu Workeru.
orphaned_provisioned_namespace Namespace existuje pro třídu, která není ani v kódu, ani deklarovaná. Přidejte pro třídu tombstone, nebo třídu vraťte zpět do kódu a exports.
invalid_export exports položka je strukturálně neplatná, například pokud požadujete legacy-kv pro nový namespace, nebo třídu, která se mapuje na více než jeden vytvořený namespace. Opravte záznam: použijte "storage": "sqlite" pro nové jmenné prostory, nebo tuto duplicitu vyřešte pomocí deleted nebo renamed tombstone.
tombstone_delete_class_still_in_code A deleted tombstone označuje třídu, která je v kódu stále exportovaná. Nejprve odstraňte třídu z kódu a poté nasaďte tombstone.
tombstone_delete_blocked_by_external_bindings K mazanému namespace je navázán jiný Worker v účtu. Znovu nasaďte odkazující Workers bez daného bindingu a poté nasazení spusťte znovu.
tombstone_renamed_to_occupied A renamed_to cíl koliduje s existujícím namespacem pod tímto názvem. Odstraňte kolidující namespace pomocí jeho vlastního deleted tombstone v předchozím nasazení.
transferred_pending_not_found A transferred tombstone nemá odpovídající expecting-transfer položku v cíli. Nejprve nasaďte cílový Worker s expecting-transfer položku pojmenovávající tohoto Worker.
transferred_target_missing Cílový Worker uvedený v transferred_to už neexistuje. Aktualizujte transferred_to na platný cíl, nebo tombstone odeberte.
transferred_target_mismatch transferred_to neodpovídá cíli zaznamenanému u čekajícího přesunu. Nastavte transferred_to na cíl čekajícího přesunu, nebo nechte cíl zrušit svůj expecting-transfer položku před přesměrováním.
transferred_source_in_dispatch_namespace Zdrojový Worker deklarující transferred tombstone je v dispatch namespace; přesun napříč dispatch namespace není podporován. Přenos proveďte v rámci jednoho kontextu dispatch-namespace.
transferred_target_in_dispatch_namespace Cíl transferred tombstone je v dispatch namespace; přesun napříč dispatch namespace není podporován. Čekající přenos zrušíte tak, že cíl znovu nasadíte bez expecting-transfer, nebo ponechat oba Workery ve stejném kontextu.
phase_one_transfer_after_commit_mismatch Namespace cíle byl přenesen z jiného zdroje, než jaký byl deklarován. Odeberte expecting-transfer položku, přenos nelze po potvrzení přesměrovat.
phase_one_transfer_target_class_provisioned Cílový Worker pro danou třídu už namespace vlastní. Nahraďte expecting-transfer položku běžnou aktivní položkou, nebo nejprve smažte existující namespace.
phase_one_transfer_duplicate Další expecting-transfer nápověda je pro tuto třídu již v procesu zpracování. Nejprve zrušte stávající čekající přenos odebráním nebo nahrazením jeho záznamu.
phase_one_transfer_source_missing Zdrojový Worker uvedený v transfer_from v účtu neexistuje. Opravte název zdrojového Workeru.
phase_one_transfer_source_namespace_missing Zdrojový Worker pro danou třídu nemá namespace. Ujistěte se, že zdrojový Worker má třídu nasazenou dříve, než ji cílový Worker deklaruje pomocí expecting-transfer.
phase_one_transfer_source_in_dispatch_namespace Zdrojový Worker se nachází v dispatch namespace; přenos mezi dispatch namespace není podporován. Přesuňte přenos v rámci jednoho kontextu dispatch-namespace.
phase_one_transfer_target_in_dispatch_namespace Cílový Worker se nachází v dispatch namespace; přenos mezi dispatch namespace není podporován. Přesuňte přenos v rámci jednoho kontextu dispatch-namespace.
storage_type_mismatch Deklarovaný storage neodpovídá úložnému backendu zřízeného jmenného prostoru. Backendy úložiště nelze měnit za běhu. Pokud opravdu potřebujete přejít na jiný backend, odstraňte namespace a znovu ho zřiďte s novým backendem.
free_tier_requires_sqlite Plán účtu podporuje pouze jmenné prostory s podporou SQLite, ale záznam požaduje legacy-kv. Použijte "storage": "sqlite".

Omezení a limity

Migrovat ze staršího migrations tok

Stávající Workery používající migrations pole se může přesunout na exports bez jakékoli migrace dat. Zřízené jmenné prostory zůstávají na místě, mění se pouze tvar konfigurace.

Chcete-li zjistit, jaké úložiště daná třída aktuálně používá, dohledejte migraci, která ji původně vytvořila. Třídy zavedené pomocí new_sqlite_classes použít sqlite, zatímco třídy zavedené prostřednictvím new_classes použít legacy-kv.

  1. Určete, které živé třídy Durable Object váš Worker aktuálně exportuje. Každá třída s aktivním jmenným prostorem se stává živým exports položka.
  2. Nahraďte migrations pole s exports mapu. Pro každou existující třídu přidejte položku podle názvu třídy s "type": "durable-object". Přiřaďte stávající úložný backend k "storage": "sqlite" nebo "storage": "legacy-kv".
  3. Odeberte migrations pole z vaší konfigurace.
  4. Nasaďte.

Pro srovnání, ekvivalent typického migrations historie je:

{
	"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"

Budoucí změny životního cyklu (mazání, přejmenování, přenosy) probíhají výhradně prostřednictvím exports, neexistuje obdoba tag pole a není třeba uchovávat historické položky. Aktuální stav vašeho exports mapa je zdrojem pravdy.