Az Orchestrator függvénykódjának korlátozásai

Durable Functions a Azure Functions bővítménye, amellyel állapotalapú alkalmazásokat hozhat létre. A vezénylőfüggvényekkel más tartós függvények végrehajtását is vezényelheti egy függvényalkalmazásban. Az Orchestrator-függvények állapotalapúak, megbízhatóak és hosszú ideig futnak.

Vezénylői kódkorlátozások

Az Orchestrator-függvények eseményforrásokkal biztosítják a megbízható végrehajtást és a helyi változóállapot fenntartását. A vezénylőkód visszajátszási viselkedése kényszereket hoz létre az vezénylőfüggvényekben írható kód típusára. A vezénylő függvényeinek például determinisztikusnak kell lenniük: a vezénylőfüggvények többször lesznek lejátszva, és minden alkalommal ugyanazt az eredményt kell eredményezniük.

Determinisztikus API-k használata

Ez a szakasz néhány egyszerű útmutatót tartalmaz, amelyek segítenek biztosítani, hogy a kód determinisztikus legyen.

Az Orchestrator-függvények bármilyen API-t meghívhatnak a célnyelvükön. Fontos azonban, hogy a vezénylő függvények csak determinisztikus API-kat hívjanak meg. A determinisztikus API olyan API, amely mindig ugyanazt az értéket adja vissza ugyanazzal a bemenettel, függetlenül attól, hogy mikor vagy milyen gyakran hívják meg.

Az alábbi szakaszok útmutatást nyújtanak az OLYAN API-khoz és mintákhoz, amelyeket érdemes elkerülni, mert azok nem determinisztikusak. Ezek a korlátozások csak a vezénylőfüggvényekre vonatkoznak. Más függvénytípusokra nem vonatkoznak ilyen korlátozások.

Megjegyzés

Az alábbiakban számos kódkorlátozástípust ismertetünk. Ez a lista sajnos nem átfogó, és előfordulhat, hogy egyes használati esetekről nem esik szó. A vezénylőkódok írásakor a legfontosabb szempont, hogy a használt API determinisztikus-e. Ha már így gondolkodik, könnyen megértheti, hogy mely API-k használhatók biztonságosan, és melyek nem anélkül, hogy erre a dokumentált listára kellene hivatkoznia.

Dátum és idő

Az aktuális dátumot vagy időpontot visszaadó API-k nem determinisztikusak, és soha nem használhatók vezénylőfüggvényekben. Ennek az az oka, hogy minden vezénylő függvény visszajátszása más értéket eredményez. Ehelyett az Durable Functions egyenértékű API-t kell használnia az aktuális dátum vagy időpont lekéréséhez, amely a visszajátszások között konzisztens marad.

Ne használjon DateTime.Now, DateTime.UtcNowvagy azzal egyenértékű API-kat az aktuális időpont lekéréséhez. Az olyan osztályokat is el kell kerülni, mint Stopwatch amilyeneket el kell kerülni. A folyamaton belüli .NET vezénylőfüggvények esetében használja a IDurableOrchestrationContext.CurrentUtcDateTime tulajdonságot az aktuális idő lekéréséhez. A .NET izolált vezénylőfüggvényeinél használja a TaskOrchestrationContext.CurrentDateTimeUtc tulajdonságot az aktuális idő lekéréséhez.

DateTime startTime = context.CurrentUtcDateTime;
// do some work
TimeSpan totalTime = context.CurrentUtcDateTime.Subtract(startTime);

GUID-k és UUID-k

A véletlenszerű GUID-t vagy UUID-t visszaadó API-k nem determinisztikusak, mert a létrehozott érték minden visszajátszásnál eltérő. A használt nyelvtől függően a determinisztikus GUID-k vagy UUID-k létrehozására szolgáló beépített API is elérhető lehet. Ellenkező esetben egy tevékenységfüggvény használatával véletlenszerűen generált GUID-t vagy UUID-t ad vissza.

Ne használjon OLYAN API-kat, mint Guid.NewGuid() véletlenszerű GUID-k létrehozása. Ehelyett a környezeti objektum API-ját NewGuid() használva hozzon létre egy véletlenszerű GUID-t, amely biztonságos a vezénylő újrajátszásához.

Guid randomGuid = context.NewGuid();

Megjegyzés

A vezénylési környezet API-jaival létrehozott GUID-k 5-ös típusú UUID-k.

Véletlenszerű számok

Tevékenységfüggvény használatával véletlenszerű számokat ad vissza egy vezénylőfüggvénynek. A tevékenységfüggvények visszatérési értékei mindig biztonságosak a visszajátszáshoz, mert a rendszer menti őket a vezénylési előzményekbe.

Alternatív megoldásként egy fix magértékkel rendelkező véletlenszerű számgenerátor közvetlenül használható egy vezénylőfüggvényben. Ez a módszer mindaddig biztonságos, amíg az egyes vezénylési visszajátszásokhoz ugyanaz a számsor jön létre.

Kötések

A vezénylőfüggvények nem használhatnak kötéseket, beleértve még a vezénylési ügyfél - és entitásügyfél-kötéseket sem. Mindig használjon bemeneti és kimeneti kötéseket egy ügyfélen vagy tevékenységfüggvényen belül. Ez azért fontos, mert a vezénylési függvények többször is lejátszhatók, ami nemdeterminisztikus és duplikált I/O-t okoz külső rendszerekkel.

Statikus változók

Kerülje a statikus változók használatát a vezénylőfüggvényekben, mert értékük idővel változhat, ami nemdeterminisztikus futtatókörnyezeti viselkedést eredményez. Ehelyett használjon állandókat, vagy korlátozza a statikus változók használatát a tevékenységfüggvényekre.

Megjegyzés

A vezénylőfüggvényeken kívül is a statikus változók Azure Functions való használata számos okból problémás lehet, mivel nincs garancia arra, hogy a statikus állapot több függvény végrehajtása során is megmarad. A statikus változókat el kell kerülni, kivéve a nagyon specifikus használati eseteket, például a legjobb memóriabeli gyorsítótárazást a tevékenység- vagy entitásfüggvényekben.

Környezeti változók

A vezénylőfüggvényekben ne használjon környezeti változókat. Az értékek idővel változhatnak, ami nemdeterminisztikus futtatókörnyezeti viselkedést eredményez. Ha egy vezénylőfüggvénynek környezeti változóban meghatározott konfigurációra van szüksége, a konfigurációs értéket bemenetként vagy tevékenységfüggvény visszatérési értékeként kell átadnia a vezénylő függvénynek.

Hálózat és HTTP

A tevékenységfüggvények használatával kimenő hálózati hívásokat kezdeményezhet. Ha HTTP-hívást kell kezdeményeznie a vezénylő függvényből, használhatja a tartós HTTP API-kat is.

Szálblokkoló API-k

Az olyan API-k blokkolása, mint az "alvó állapot" teljesítménybeli és skálázási problémákat okozhat a vezénylői függvények esetében, ezért el kell kerülni. A Azure Functions használatalapú csomagban akár szükségtelen végrehajtási időköltségeket is eredményezhetnek. Alternatív megoldásokkal blokkolhatja az API-kat, ha elérhetők. A Tartós időzítőkkel például olyan késleltetéseket hozhat létre, amelyek biztonságosak a visszajátszáshoz, és nem számítanak bele a vezénylő függvény végrehajtási idejébe.

Aszinkron API-k

Az orchestrator-kódnak soha nem szabad aszinkron műveletet indítania, kivéve azokat, amelyeket a vezénylési eseményindító környezeti objektuma határoz meg. Például soha ne használja a , Task.Delaya és HttpClient.SendAsync a parancsot Task.Runa .NET-ben vagy setTimeoutsetInterval a JavaScriptben. A vezénylőfüggvények csak tartós SDK API-k használatával ütemezhetnek aszinkron munkát, például tevékenységfüggvényeket. Minden más típusú aszinkron hívásnak tevékenységfüggvényeken belül kell lennie.

Aszinkron JavaScript-függvények

A JavaScript-vezénylő függvényeket mindig szinkron generátorfüggvényként deklarálja. Nem deklarálhat JavaScript-vezénylőfüggvényeket, async mert a Node.js futtatókörnyezet nem garantálja, hogy az aszinkron függvények determinisztikusak.

Python-koroutine-k

A Python vezénylőfüggvényeket nem deklarálhatja coroutine-ként. Más szóval soha ne deklarálja a Python vezénylőfüggvényeket a async kulcsszóval, mert a coroutine szemantika nem igazodik a Durable Functions visszajátszási modellhez. A Python vezénylőfüggvényeit mindig generátorként kell deklarálnia, ami azt jelenti, hogy az API-t a context helyett kell használnia yieldawait.

.NET-szálkezelés API-k

A Durable Task Framework egyetlen szálon futtatja a vezénylési kódot, és nem tud más szálakkal kommunikálni. Ha aszinkron folytatásokat futtat egy feldolgozókészlet-szálon, a vezénylés végrehajtása nem meghatározott végrehajtást vagy holtpontot eredményezhet. Ezért a vezénylő függvények szinte soha nem használhatnak szálkezelés API-kat. Például soha ne használja ConfigureAwait(continueOnCapturedContext: false) vezénylőfüggvényekben. Ez biztosítja, hogy a feladatfolytatások a vezénylő függvény eredetijén SynchronizationContextfussanak.

Megjegyzés

A Durable Task Framework megpróbálja észlelni a nem vezénylőszálak véletlen használatát a vezénylőfüggvényekben. Ha szabálysértést talál, a keretrendszer egy NonDeterministicOrchestrationException kivételt jelez. Ez az észlelési viselkedés azonban nem fog minden szabálysértést észlelni, és nem szabad attól függenie.

Verziókezelés

A tartós vezénylés napokig, hónapokig, évekig vagy akár örökké is folyamatosan futhat. A befejezetlen vezényléseket befolyásoló Durable Functions alkalmazások kódfrissítései megszakíthatják a vezénylések visszajátszási viselkedését. Ezért fontos körültekintően megtervezni a kódfrissítéseket. A kód verziószámozásának részletesebb leírását a verziószámozásról szóló cikkben találja.

Tartós feladatok

Megjegyzés

Ez a szakasz a Durable Task Framework belső implementációjának részleteit ismerteti. A tartós függvényeket anélkül használhatja, hogy ismerné ezeket az információkat. Ez csak a visszajátszási viselkedés megértését szolgálja.

A vezénylői függvényekben biztonságosan várakozó feladatokat időnként tartós feladatoknak nevezzük. A Durable Task Framework létrehozza és kezeli ezeket a feladatokat. Ilyenek például a , WaitForExternalEventés CreateTimer a .NET-vezénylő függvények által CallActivityAsyncvisszaadott feladatok.

Ezeket a tartós feladatokat a .NET objektumlistája TaskCompletionSource belsőleg kezeli. A visszajátszás során ezek a feladatok a vezénylőkód végrehajtásának részeként jönnek létre. A kézbesítő befejezi a megfelelő előzményesemények számbavételét.

A feladatok szinkron módon, egyetlen szál használatával lesznek végrehajtva, amíg az összes előzményt vissza nem játsszák. Azok a tartós feladatok, amelyek nem fejeződnek be az előzmény-visszajátszás végére, megfelelő műveleteket hajtanak végre. Előfordulhat például, hogy egy üzenet meghív egy tevékenységfüggvényt.

Ez a szakasz a futtatókörnyezet viselkedésének leírásával segít megérteni, hogy egy vezénylőfüggvény miért nem használható await vagy yield nem használható feladatban. Ennek két oka lehet: a kézbesítőszál nem tudja megvárni a feladat befejezését, és a feladat visszahívása potenciálisan ronthatja a vezénylő függvény nyomkövetési állapotát. A szabálysértések észleléséhez futásidejű ellenőrzéseket is végeznek.

Ha többet szeretne megtudni arról, hogy a Durable Task Framework hogyan hajtja végre a vezénylői függvényeket, tekintse meg a Tartós feladat forráskódját a GitHubon. Lásd: TaskOrchestrationExecutor.cs és TaskOrchestrationContext.cs.

Következő lépések