Jos Durable Object -kutsu epäonnistui verkkovirheen vuoksi, kehittäjän piti aiemmin usein päättää, kannattaako se lähettää uudelleen. 5. marraskuuta 2026 alkaen osan uudelleenyrityksistä hoitaa Cloudflaren runtime: se yrittää automaattisesti uudelleen tiettyjä epäonnistuneita fetch()-kutsuja ja stubin kautta tehtyjä RPC-kutsuja. Sovelluskoodin kannalta keskeinen kysymys on nyt täsmällisempi: voiko tietyn metodin suorittaa turvallisesti toisen kerran?
Vastaus riippuu siitä, missä vaiheessa yhteys katkesi. Runtime yrittää automaattisesti uudelleen joitakin kutsuja ja suojaa oletusarvoisesti kaksoissuoritukselta. Jos toimituksen onnistumisesta ei ole varmuutta, se käyttää samaa pyyntötunnistetta, ja objekti hylkää uudelleenyrityksen, jos se on jo vastaanottanut ensimmäisen yrityksen. Erikseen retryable()-merkinnällä varustettu metodi toimii toisin: se voidaan suorittaa uudelleen, vaikka ensimmäinen yritys olisi jo saapunut objektille. Siksi merkintä sopii vain toiminnoille, joiden uudelleen suorittaminen on turvallista sekä tilan että sivuvaikutusten kannalta.
Mitä runtime yrittää uudelleen
Cloudflaren 5. marraskuuta julkaistun ilmoituksen mukaan uudelleenyritykset koskevat Workerista tai toisesta Durable Objectista tehtyjä Durable Objectien fetch()- ja RPC-kutsuja. Stubin kautta tehtävissä kutsuissa oletuksena on ensimmäinen yritys ja enintään neljä uudelleenyritystä; uusia yrityksiä ei aloiteta enää 10 sekuntia kutsun aloittamisen jälkeen.

Edellytyksenä on virhe, jolla on .retryable-ominaisuus. Pyyntö ei esimerkiksi ehkä tavoita objektia, koska sitä käynnistetään uudelleen tai siirretään. Runtime voi yrittää uudelleen myös silloin, kun yhteys katkesi eikä voida tietää, ehtikö objekti vastaanottaa pyynnön. Jos objekti on jo saanut pyynnön, samalla tunnisteella tehty uudelleenyritys hylätään. Runtime ei yritä uudelleen Durable Objectin koodin aiheuttamia virheitä, .overloaded-virheitä eikä 500:n kaltaisia HTTP-vastauksia: ne ovat käsittelijän vastauksia, eivät toimitusvirheitä.
Miksi toimituksen uudelleenyritys ei tarkoita toiminnon uudelleensuoritusta
Pyynnön uudelleenlähetys ei itsessään tarkoita, että metodi suoritetaan toisen kerran. Jos tulos on epävarma, runtime lähettää pyynnön samalla tunnisteella; jos objekti vastaanotti alkuperäisen yrityksen, se hylkää uudelleenyrityksen. Näin estetään metodin suorittaminen uudelleen oletustilassa esimerkiksi tilanteessa, jossa yksi verkkohäiriö johtaisi uuteen veloitukseen tai tietueen luomiseen.

Raja muuttuu, kun metodi merkitään cloudflare:durable-objects-moduulin retryable()-funktiolla. Tällöin objekti saa suorittaa metodin uudelleen, jos ensimmäinen yritys on saattanut jo alkaa. Cloudflare antaa kaksi esimerkkiä: tuotteen määrän asettaminen tiettyyn arvoon on idempotenttia, mutta määrän kasvattaminen yhdellä ei ole. Ensimmäisen toiminnon toisto asettaa saman arvon, kun taas toisen toisto lisää vielä yhden yksikön.
Tarkista tallennustilan lopputuloksen lisäksi kaikki metodin vaikutukset. Jos uudelleen suorittaminen luo uuden maksun, lähettää viestin tai käynnistää ulkoisen toiminnon, Durable Objectin sisäisen tilan pysyminen samana ei tee toistosta turvallista. Merkintä sopii tilanteisiin, joissa toisto ei muuta tuloksen merkitystä eikä monista sivuvaikutuksia.
Milloin eksplisiittisestä idempotenssista on hyötyä
Arvon asettaminen, tilannevedoksen tallentaminen tai kentän päivittäminen tunnettuun arvoon tuottaa usein saman tuloksen toistettaessa. Tällaisissa metodeissa retryable() voi auttaa kutsua onnistumaan myös silloin, kun yhteys katkeaa käsittelyn alettua.
Toiminnot kuten ”lisää”, ”luo toinen”, ”veloita” ja ”lähetä” vaativat yleensä muunlaista suojausta. Varmista ennen uudelleensuorituksen sallimista, että liiketoimintatoiminto tunnistaa kaksoiskappaleet tai että se on toteutettu niin, ettei toisto aiheuta toista vaikutusta. Funktion nimi ei takaa mitään: tarkista kaikki metodin sisäiset tilamuutokset ja ulkoiset toiminnot.
retryable()-funktion rooli on rajattu: se sallii suorituksen toistamisen, kun ei tiedetä, saavuttiko ensimmäinen kutsu kohteensa. Se ei muuta niiden virheiden luetteloa, joihin runtime reagoi, eikä kasvata yritysten määrää. Merkintä koskee funktiota; metodin korvattu tai kääritty versio ei peri sitä automaattisesti, ellei sitäkin merkitä erikseen.
Mitä kannattaa tarkistaa jo toimivasta projektista
Todennäköisin tarkistettava kohta ovat omat uudelleenyrityssilmukat Durable Objects -kutsujen ympärillä. Nyt jokainen tällainen yritys voi sisältää myös runtimen uudelleenyrityksiä, joten kutsujen kokonaismäärä voi olla suurempi kuin pelkkä sovelluksen asettama määrä. Cloudflare suosittelee vähentämään omien yritysten määrää tai asettamaan stubille maxRetries: 0, jos sovellus hallitsee uudelleenyrityksiä.
Yksittäisen stubin rajat asetetaan kutsuttaessa get()- tai getByName()-metodia. Parametri maxRetries määrittää ensimmäisen yrityksen jälkeisten uudelleenyritysten määräksi nollasta kymmeneen; timeoutMs määrittää aikavälin, jonka jälkeen uusia yrityksiä ei enää aloiteta, 500–60 000 millisekuntia. Asetukset koskevat kyseisen stubin kautta tehtyjä kutsuja. retryable()-ominaisuus ja retry-objekti edellyttävät Wrangler-versiota 4.158.0 tai uudempaa.
Hyödyllisessä tarkistuksessa esitetään jokaisesta kutsusta kolme kysymystä: voiko se muuttaa tilaa useammin kuin kerran; toistaako se ulkoiset sivuvaikutukset; onko sovelluksella oma uudelleenyrityskäytäntö. Päätä sen jälkeen, käyttääkö kyseinen stub oletusarvoja vai omia rajoja. Idempotenttien metodien kohdalla voidaan erikseen harkita eksplisiittistä merkintää; muiden kohdalla suojaus kannattaa jättää käyttöön ja tarkistaa virhetilanteen käsittely, kun ensimmäisen yrityksen tulosta ei tiedetä.
Seuraus: vastuu siirtyy metodin rajalle
Automaattinen uudelleenyritys poistaa sovelluskoodista osan verkkologiikasta, mutta toiminnon uudelleensuorituksen sallittavuus on yhä toiminnon ominaisuus. Runtime voi yrittää toimitusta turvallisesti uudelleen ja pysähtyä, jos se ei tiedä, suoritettiinko kutsu. Kehittäjä voi sallia metodin toiston vahvistamalla, ettei se monista tilamuutoksia tai sivuvaikutuksia.
Siksi päivitystä kannattaa tarkastella kuljetustason ja käsittelijän välisen sopimuksen muutoksena. Tarkista ensin omat retry-silmukat ja sivuvaikutusten toistettavuus; määritä sen jälkeen tarvittavat rajat stubeille. Näin lyhyiden häiriöiden sietokyky yhdistyy niiden toimintojen hallintaan, joissa toisella suorituskerralla on todellisia seurauksia.