Omedelbara och fördröjda bekräftelser
I den här artikeln får du lära dig skillnaderna mellan omedelbara och fördröjda bekräftelser.
Omedelbar bekräftelse
För många program vill vi se till att händelser bekräftas omedelbart, så att den bevarade versionen inte släpar efter den aktuella versionen i minnet, och vi riskerar inte att förlora det senaste tillståndet om kornet ska misslyckas. Vi kan garantera detta genom att följa dessa regler:
- Bekräfta alla RaiseEvent anrop som använder ConfirmEvents innan kornmetoden returneras.
- Kontrollera att aktiviteter som returneras av RaiseConditionalEvent slutförda innan kornmetoden returneras.
- Undvik ReentrantAttribute eller AlwaysInterleaveAttribute attribut, så att endast ett kornanrop kan bearbetas i taget.
Om vi följer dessa regler innebär det att när en händelse har aktiverats kan ingen annan kornkod köras förrän händelsen har skrivits till lagring. Därför är det omöjligt att observera inkonsekvenser mellan versionen i minnet och versionen i lagringen. Även om detta ofta är exakt vad vi vill ha, har det också några potentiella nackdelar.
Potentiella nackdelar
Om anslutningen till ett fjärrkluster eller lagring tillfälligt avbryts blir kornet otillgängligt: i praktiken kan kornet inte köra någon kod medan den fastnar i väntan på att bekräfta händelserna, vilket kan ta en obestämd tid (loggkonsekvensprotokollet fortsätter att försöka tills lagringsanslutningen återställs).
När du hanterar många uppdateringar av en enskild korninstans kan det till exempel bli mycket ineffektivt att bekräfta dem en i taget, till exempel orsaka dåligt dataflöde.
Fördröjd bekräftelse
För att förbättra tillgängligheten och dataflödet i de situationer som nämns ovan kan korn välja att göra ett eller båda av följande:
- Tillåt att kornmetoder genererar händelser utan att vänta på bekräftelse.
- Tillåt återaktivering, så att kornet kan fortsätta bearbeta nya anrop även om tidigare anrop fastnar i väntan på bekräftelse.
Det innebär att kornkod kan köras medan vissa händelser fortfarande håller på att bekräftas. API:et JournaledGrain<TGrainState,TEventBase> har vissa specifika bestämmelser för att ge utvecklare exakt kontroll över hur de ska hantera obekräftade händelser som för närvarande är under flygning.
Följande egenskap kan undersökas för att ta reda på vilka händelser som för närvarande är obekräftade:
IEnumerable<EventType> UnconfirmedEvents { get; }
Eftersom det tillstånd som returneras av JournaledGrain<TGrainState,TEventBase>.State egenskapen inte inkluderar effekten av obekräftade händelser, finns det också en alternativ egenskap
StateType TentativeState { get; }
Som returnerar ett "preliminärt" tillstånd som hämtats från "State" genom att tillämpa alla obekräftade händelser. Det preliminära tillståndet är i huvudsak en "bästa gissning" på vad som sannolikt kommer att bli nästa bekräftade tillstånd efter att alla obekräftade händelser har bekräftats. Det finns dock ingen garanti för att det faktiskt kommer att göra det, eftersom kornet kan misslyckas, eller för att händelserna kan tävla mot andra händelser och förlora, vilket gör att de avbryts (om de är villkorade) eller visas vid en senare position i sekvensen än förväntat (om de är ovillkorliga).
Samtidighetsgarantier
Observera att Orleans turbaserad schemaläggning (samtidighet i samarbete) alltid gäller, även när du använder återaktivering eller fördröjd bekräftelse. Det innebär att även om flera metoder kan vara på gång kan bara en köras aktivt – alla andra har fastnat i väntan, så det finns aldrig några verkliga raser som orsakas av parallella trådar.
Observera särskilt att:
- Egenskaperna State, TentativeState, Versionoch UnconfirmedEvents kan ändras under körningen av en metod.
- Men sådana ändringar kan bara ske när de fastnar i väntan.
Dessa garantier förutsätter att användarkoden håller sig inom den rekommenderade metoden för uppgifter och asynkronisering/inväntning (i synnerhet använder inte trådpoolsuppgifter, eller använder dem bara för kod som inte anropar kornfunktioner och som väntar på rätt sätt).