INTEGRITY Dokumentace

Referenční dokumentace API

Tato stránka popisuje API bindingu Worker Loaderu za předpokladu, že máte nakonfigurovali takový binding jako env.LOADER.

load

env.LOADER.load(code WorkerCode) WorkerStub

Načte Worker z poskytnutého WorkerCode a vrátí WorkerStub která může sloužit k vyvolání Workeru.

Na rozdíl od get(), load() neukládá do cache podle ID. Každé volání vytvoří nový Worker.

Použijte load() když je kód vždy nový, například u jednorázových volání nástrojů generovaných AI.

get

env.LOADER.get(id string, getCodeCallback () => Promise<WorkerCode>): WorkerStub

Načte Worker se zadaným ID a vrátí WorkerStub která může sloužit k vyvolání Workeru.

Pro pohodlí loader implementuje kešování izolátů. Když se poprvé objeví nové ID, načte se nový izolát. Ten pak může nějakou dobu zůstat v paměti zahřátý. Pokud pozdější volání loaderu požádají o stejné ID, může se znovu vrátit existující izolát místo vytvoření nového. Není to však zaručeno: pozdější volání se stejným ID může místo toho spustit zcela nový izolát.

Kdykoli systém rozhodne, že potřebuje spustit nový isolate, a nemá kód dosud uložený v cache, vyvolá codeCallback k získání kódu Workeru. Jde o asynchronní callback, takže aplikace může kód v případě potřeby načíst ze vzdáleného úložiště. Callback vrací WorkerCode objekt (popsán níže).

Kvůli kešování byste měli zajistit, aby callback při volání se stejným ID vždy vrátil naprosto stejný obsah. Pokud se na obsahu cokoli změní, musíte použít nové ID. Pokud se ale obsah nezměnil, je nejlepší použít znovu stejné ID, abyste využili výhod kešování. Pokud WorkerCode se pokaždé liší, můžete předat náhodné ID.

Můžete například použít ID ve tvaru <worker-name>:<version-number>, kde se číslo verze zvyšuje při každé změně kódu. Případně můžete ID počítat z hashe kódu a konfigurace, takže jakákoli změna povede k novému ID.

get() vrací WorkerStub, který lze použít k odesílání požadavků na načtený Worker. Stub se vrací synchronně, není potřeba na něj čekat pomocí await. Pokud Worker ještě není načtený, požadavky na stub počkají, až se Worker načte, a teprve poté budou doručeny. Pokud načítání selže, požadavek vyvolá výjimku.

Není nikdy zaručeno, že dva požadavky poputují do stejného izolátu. I když použijete stejný WorkerStub k vytvoření více požadavků, mohou se vykonat v různých izolátech. Callback předaný do loader.get() může být volána libovolněkrát (i když je neobvyklé, aby byla volána víckrát než jednou).

WorkerCode

Toto je struktura, kterou vrací getCodeCallback k reprezentaci workeru.

compatibilityDate string

compatibility date pro Worker. Má to stejný význam jako compatibility_date nastavení v konfiguračním souboru Wrangler.

compatibilityFlags string[] Optional

Volitelný seznam compatibility flags rozšiřuje compatibility date. Má to stejný význam jako compatibility_flags nastavení v konfiguračním souboru Wrangler.

allowExperimental boolean Optional

Pokud je hodnota true, budou experimentální compatibility flags povoleny v compatibilityFlags. Aby to bylo možné nastavit, musí mít worker, který loader volá, sám nastaven compatibility flag "experimental" nastaven. Experimentální flagy nelze v produkci povolit.

mainModule string

Název hlavního modulu Workeru. Musí se jednat o jeden z modulů uvedených v modules.

modules Record<string, string | Module>

Objekt slovníku, který mapuje názvy modulů na jejich textový obsah. Pokud je obsah modulu obyčejný řetězec, musí mít název modulu příponu souboru označující jeho typ, a to buď .js nebo .py.

Obsah modulu lze také zadat jako objekt, aby bylo možné určit jeho typ nezávisle na názvu. Povolené objekty jsou:

globalOutbound ServiceStub | null Optional

Řídí, zda má dynamický Worker přístup k síti. Globální fetch() a connect() funkce (pro vytváření požadavků HTTP, respektive připojení TCP) lze zablokovat nebo přesměrovat, a Worker tak izolovat.

Pokud globalOutbound není zadán, výchozí chování dědí síťový přístup nadřazeného prvku, což obvykle znamená, že dynamic Worker bude mít plný přístup k veřejnému internetu.

Pokud globalOutbound je null, pak bude dynamic Worker zcela odpojen od sítě. Obě fetch() a connect() vyvolá výjimky.

globalOutbound lze také nastavit na libovolný service binding, včetně service bindingů nadřazeného workeru v env a také loopback bindingy z ctx.exports.

Použití ctx.exports je obzvláště užitečné, protože umožňuje dále přizpůsobit binding pro konkrétní sandbox nastavením hodnoty ctx.props která by mu měla být předána zpět. props může obsahovat informace, podle kterých identifikujete konkrétní dynamic Worker, jenž požadavek odeslal.

Například:

import { WorkerEntrypoint } from "cloudflare:workers";

export class Greeter extends WorkerEntrypoint {
	fetch(request) {
		return new Response(`Hello, ${this.ctx.props.name}!`);
	}
}

export default {
	async fetch(request, env, ctx) {
		let worker = env.LOADER.get("alice", () => {
			return {
				// Redirect the worker's global outbound to send all requests
				// to the `Greeter` class, filling in `ctx.props.name` with
				// the name "Alice", so that it always responds "Hello, Alice!".
				globalOutbound: ctx.exports.Greeter({ props: { name: "Alice" } }),

				// ... code ...
			};
		});

		return worker.getEntrypoint().fetch(request);
	},
};

env object

Objekt prostředí (environment), který se má poskytnout dynamickému Workeru.

Díky tomu můžete Workeru poskytnout vlastní bindingy.

env se serializuje a přenese do dynamic Workeru, kde se použije přímo jako hodnota env tam. Může obsahovat:

Druhý bod je klíčem k vytváření vlastních bindingů: binding můžete definovat s jakýmkoli libovolným API tak, že definujete WorkerEntrypoint třída implementující API RPC a následným předáním dynamic Workeru jako Service Binding.

Díky použití ctx.exports loopback bindingy můžete dále přizpůsobit pro konkrétní dynamic Worker nastavením ctx.props, stejně jako je popsáno u globalOutbound, výše.

import { WorkerEntrypoint } from "cloudflare:workers";

// Implement a binding which can be called by the dynamic Worker.
export class Greeter extends WorkerEntrypoint {
	greet() {
		return `Hello, ${this.ctx.props.name}!`;
	}
}

export default {
	async fetch(request, env, ctx) {
		let worker = env.LOADER.get("alice", () => {
			return {
				env: {
					// Provide a binding which has a method greet() which can be called
					// to receive a greeting. The binding knows the Worker's name.
					GREETER: ctx.exports.Greeter({ props: { name: "Alice" } }),
				},

				// ... code ...
			};
		});

		return worker.getEntrypoint().fetch(request);
	},
};

tails ServiceStub[] Optional

Můžete zadat jeden nebo více Tail Workers která bude sledovat logy konzole, chyby a další podrobnosti o vykonávání dynamicky načteného workeru. Po dokončení požadavku na dynamicky načtený Worker se do Tail Workeru doručí tail event. Tail Worker můžete jako vždy implementovat jako alternativní entrypoint ve svém nadřazeném Workeru, na který odkážete pomocí ctx.exports:

import { WorkerEntrypoint } from "cloudflare:workers";

export default {
	async fetch(request, env, ctx) {
		let worker = env.LOADER.get("alice", () => {
			return {
				// Send logs, errors, etc. to `LogTailer`. We pass `name` in the
				// `ctx.props` so that `LogTailer` knows what generated the logs.
				// (You can pass anything you want in `props`.)
				tails: [ctx.exports.LogTailer({ props: { name: "alice" } })],

				// ... code ...
			};
		});

		return worker.getEntrypoint().fetch(request);
	},
};

export class LogTailer extends WorkerEntrypoint {
	async tail(events) {
		let name = this.ctx.props.name;

		// Send the logs off to our log endpoint, specifying the worker name in
		// the URL.
		//
		// Note that `events` will always be an array of size 1 in this scenario,
		// describing the event delivered to the dynamically-loaded Worker.
		await fetch(`https://example.com/submit-logs/${name}`, {
			method: "POST",
			body: JSON.stringify(events),
		});
	}
}