Om ett anrop till ett Durable Object slutade med ett nätverksfel behövde utvecklaren tidigare ofta avgöra om det skulle skickas igen. Sedan den 5 november 2026 hanterar Cloudflares runtime-miljö en del av dessa återförsök: den försöker automatiskt igen vid vissa misslyckade anrop till fetch() och RPC via en stub. För applikationskoden är den viktiga frågan nu mer precis: kan just den här metoden köras igen på ett säkert sätt?
Svaret beror på var anslutningen bröts. Runtime-miljön försöker automatiskt igen vid vissa anrop och skyddar som standard mot dubbel körning. Vid osäker leverans använder den samma begärande-ID, och objektet avvisar återförsöket om det redan har tagit emot det första försöket. En metod som uttryckligen har markerats med retryable() fungerar annorlunda: den kan köras igen även om det första försöket redan nådde objektet. Därför bör markeringen endast användas för operationer vars upprepning är säker både för tillståndet och för sidoeffekterna.
Vad runtime-miljön försöker igen
Enligt Cloudflares tillkännagivande den 5 november omfattar återförsöken anrop till fetch() och RPC mot Durable Objects, gjorda av en Worker eller ett annat Durable Object. För anrop via en stub görs som standard ett första försök och upp till fyra återförsök. Nya försök startas inte senare än 10 sekunder efter att anropet inleddes.

Villkoret är ett fel med egenskapen .retryable. Till exempel kan begäran ha misslyckats med att nå objektet eftersom det startades om eller flyttades. Runtime-miljön kan också försöka igen om anslutningen bröts och det är oklart om objektet hann ta emot begäran. Om objektet redan tog emot den avvisas återförsöket med samma ID. Runtime-miljön försöker inte igen vid fel som kastas av Durable Objects kod, fel med .overloaded eller HTTP-svar som 500: det är svar från hanteraren, inte leveransfel.
Varför en ny leverans inte är samma sak som att köra operationen igen
Att begäran skickas igen innebär inte i sig att metoden körs en andra gång. Vid ett osäkert resultat skickar runtime-miljön begäran med samma ID; om objektet tog emot det första försöket avvisar det återförsöket. I normalläget förhindrar detta att metoden körs igen, till exempel att en debitering görs på nytt eller att en post skapas igen på grund av ett enda nätverksfel.

Gränsen förändras när metoden markeras med retryable() från cloudflare:durable-objects. Då får objektet köra metoden igen om det första försöket kan ha påbörjats. Cloudflare ger två exempel: att tilldela en produkt ett bestämt antal är idempotent; att öka antalet med ett är det inte. En upprepning av den första åtgärden anger samma värde, medan en upprepning av den andra lägger till ytterligare en enhet.
Kontrollera inte bara det slutliga tillståndet i lagringen, utan även alla metodens effekter. Om en upprepning skapar en extra betalning, skickar ett meddelande eller utlöser en extern åtgärd blir upprepningen inte säker bara för att tillståndet i Durable Object är detsamma. Markeringen passar när upprepningen inte ändrar resultatets innebörd och inte duplicerar sidoeffekter.
När uttrycklig idempotens är användbar
Att ange ett värde, spara en ögonblicksbild av tillståndet eller uppdatera ett fält till ett känt värde ger ofta samma resultat vid en upprepning. För sådana metoder kan retryable() göra att anropet slutförs framgångsrikt efter ett anslutningsavbrott som inträffar efter att behandlingen har börjat.
Åtgärder som ”lägg till”, ”skapa en till”, ”debitera” och ”skicka” kräver vanligtvis ett annat slags skydd. Innan du tillåter att de körs igen bör du försäkra dig om att affärsoperationen känner igen dubbletter eller är utformad så att en upprepning inte skapar en extra effekt. Funktionsnamnet i sig garanterar ingenting: kontrollera alla tillståndsändringar och externa åtgärder i metoden.
retryable() har en avgränsad funktion: den tillåter att en metod körs igen när det inte går att avgöra om det första anropet kom fram. Den ändrar inte vilka fel runtime-miljön reagerar på och ökar inte antalet försök. Flaggan gäller funktionen; en åsidosatt eller omsluten version av metoden ärver den inte automatiskt, utan måste också markeras uttryckligen.
Vad du bör kontrollera i ett befintligt projekt
Den mest sannolika platsen för en översyn är projektets egna återförsöksloopar runt anrop till Durable Objects. Nu kan varje sådant försök i sin tur innehålla återförsök från runtime-miljön, så det totala antalet anrop kan bli större än vad enbart applikationen anger. Cloudflare rekommenderar att minska antalet egna försök eller ange maxRetries: 0 för stubben om din kod hanterar återförsöken.
Gränserna för en specifik stub anges när get() eller getByName() anropas. Parametern maxRetries anger från noll till tio återförsök efter det första försöket; timeoutMs anger tidsgränsen efter vilken inga nya försök startas, från 500 till 60 000 millisekunder. Inställningarna gäller anrop via den aktuella stubben. Funktionerna retryable() och objektet retry kräver Wrangler 4.158.0 eller senare.
En användbar översyn börjar med tre frågor för varje anrop: kan det ändra tillståndet mer än en gång; upprepar det externa sidoeffekter; har applikationen en egen återförsökspolicy? Bestäm sedan om den aktuella stubben ska använda standardvärden eller egna gränser. För idempotenta metoder kan du separat överväga en uttrycklig markering; för övriga metoder bör du behålla skyddet och kontrollera felhanteringen när resultatet av det första försöket är okänt.
Följden: ansvaret flyttas till metodgränsen
Automatiska återförsök flyttar en del av nätverkslogiken bort från applikationskoden, men beslutet om det är tillåtet att köra en metod igen hör fortfarande till själva operationen. Runtime-miljön kan försöka leverera begäran igen på ett säkert sätt och avbryta om den inte vet om anropet redan har körts. Utvecklaren kan tillåta att metoden körs igen genom att uttryckligen bekräfta att den inte duplicerar tillståndsändringar eller sidoeffekter.
Uppdateringen bör därför ses som en förändring av kontraktet mellan transportlagret och hanteraren. Börja med att kontrollera egna återförsöksloopar och om sidoeffekter kan upprepas; konfigurera sedan gränserna för de stubbar där det behövs. På så sätt kan inbyggd motståndskraft mot kortvariga fel kombineras med kontroll över operationer där en andra körning har ett verkligt pris.