Hosszú ideig futó műveletek a Javához készült Azure SDK-ban
Ez a cikk áttekintést nyújt a javai Azure SDK-val végzett hosszú ideig futó műveletek használatáról.
Bizonyos azure-beli műveletek végrehajtása hosszabb időt vehet igénybe. Ezek a műveletek nem tartoznak a gyors kérések/ válaszfolyamatok szabványos HTTP-stílusához. A forrás URL-címéről például egy Storage-blobba másolhat adatokat, vagy betanítást végezhet egy modellben az űrlapok felismerésére, ez néhány másodperctől néhány percig is eltarthat. Ezeket a műveleteket hosszú ideig futó műveleteknek nevezzük, és gyakran rövidítve "LRO"-ként. Az LRO végrehajtása a kért művelettől és a kiszolgálóoldalon végrehajtandó folyamattól függően másodperceket, perceket, órákat, napokat vagy hosszabb időt is igénybe vehet.
Az Azure Java-ügyfélkódtáraiban létezik egy konvenció, amely szerint minden hosszú ideig futó művelet az begin
előtaggal kezdődik. Ez az előtag azt jelzi, hogy ez a művelet hosszú ideig fut, és hogy a művelettel való interakció módja kissé eltér a szokásos kérés- és válaszfolyamattól. Az előtag mellett begin
a művelet visszatérési típusa is eltér a szokásostól, így lehetővé teszi a hosszú ideig futó műveletek teljes körét. A Java-hoz készült Azure SDK-ban a legtöbb dologhoz hasonlóan szinkron és aszinkron API-k is léteznek a hosszú ideig futó műveletekhez:
- Szinkron ügyfelek esetén a hosszan futó műveletek egy példányt
SyncPoller
adnak vissza. - Az aszinkron ügyfelekben a hosszan futó műveletek egy példányt
PollerFlux
adnak vissza.
Mindkettő SyncPoller
, és PollerFlux
az ügyféloldali absztrakciók célja a hosszú ideig futó kiszolgálóoldali műveletek közötti interakció egyszerűsítése. A cikk további része az ilyen típusok használatakor ajánlott eljárásokat ismerteti.
Szinkron, hosszú ideig futó műveletek
A visszaküldött API-k SyncPoller
meghívása azonnal elindítja a hosszú ideig futó műveletet. Az API azonnal visszaadja az SyncPoller
eredményt, így nyomon követheti a hosszú ideig futó művelet előrehaladását, és lekérheti a végeredményt. Az alábbi példa bemutatja, hogyan figyelheti meg egy hosszú ideig futó művelet előrehaladását a SyncPoller
.
SyncPoller<UploadBlobProgress, UploadedBlobProperties> poller = syncClient.beginUploadFromUri(<URI to upload from>)
PollResponse<UploadBlobProgress> response;
do {
response = poller.poll();
System.out.println("Status of long running upload operation: " + response.getStatus());
Duration pollInterval = response.getRetryAfter();
TimeUnit.MILLISECONDS.sleep(pollInterval.toMillis());
} while (!response.getStatus().isComplete());
Ez a példa a poll()
módszer SyncPoller
használatával kéri le a hosszú ideig futó művelet előrehaladásával kapcsolatos információkat. Ez a kód kinyomtatja az állapotot a konzolon, de egy jobb implementáció az állapot alapján releváns döntéseket hozna.
A getRetryAfter()
metódus információt ad vissza arról, hogy mennyi ideig kell várni a következő szavazás előtt. A legtöbb azure-beli hosszú ideig futó művelet a HTTP-válasz részeként adja vissza a lekérdezés késleltetését (azaz a gyakran használt retry-after
fejlécet). Ha a válasz nem tartalmazza a lekérdezés késleltetését, akkor a getRetryAfter()
metódus a hosszú ideig futó művelet meghívásakor megadott időtartamot adja vissza.
A fenti példa hurkot do..while
használ a hosszú ideig futó művelet befejezéséig történő ismételt lekérdezéshez. Ha nem érdeklik ezek a köztes eredmények, akkor ehelyett hívhatja.waitForCompletion()
Ez a hívás addig blokkolja az aktuális szálat, amíg a hosszan futó művelet be nem fejeződik, és visszaadja az utolsó szavazási választ:
PollResponse<UploadBlobProgress> response = poller.waitForCompletion();
Ha az utolsó szavazási válasz azt jelzi, hogy a hosszú ideig futó művelet sikeresen befejeződött, a végeredmény a következővel getFinalResult()
kérhető le:
if (LongRunningOperationStatus.SUCCESSFULLY_COMPLETED == response.getStatus()) {
UploadedBlobProperties result = poller.getFinalResult();
}
További hasznos API-k a SyncPoller
következők:
waitForCompletion(Duration)
: várja meg, amíg a hosszú ideig futó művelet befejeződik, a megadott időtúllépési időtartamig.waitUntil(LongRunningOperationStatus)
: várjon, amíg a megadott hosszú ideig futó művelet állapota megérkezik.waitUntil(LongRunningOperationStatus, Duration)
: várjon, amíg a megadott hosszú ideig futó művelet állapota meg nem érkezik, vagy amíg a megadott időtúllépési időtartam lejár.
Aszinkron, hosszú ideig futó műveletek
Az alábbi példa bemutatja, hogyan lehet megfigyelni egy PollerFlux
hosszú ideig futó műveletet. Az aszinkron API-kban a hálózati hívások egy másik szálon zajlnak, mint a hívást kezdeményező subscribe()
fő szál. Ez azt jelenti, hogy a fő szál az eredmény rendelkezésre állása előtt leállhat. Önnek kell gondoskodnia arról, hogy az alkalmazás ne lépjen ki, mielőtt az aszinkron művelet befejeződik.
Az aszinkron API azonnal visszaadja PollerFlux
a műveletet, de maga a hosszú ideig futó művelet nem indul el, amíg elő nem iratkozik a PollerFlux
. Ez a folyamat az összes Flux
-based API működése. Az alábbi példa egy hosszú ideig futó aszinkron műveletet mutat be:
asyncClient.beginUploadFromUri(...)
.subscribe(response -> System.out.println("Status of long running upload operation: " + response.getStatus()));
Az alábbi példában időszakos állapotfrissítéseket fog kapni a hosszú ideig futó műveletről. Ezekkel a frissítésekkel megállapíthatja, hogy a hosszú ideig futó művelet továbbra is a várt módon működik-e. Ez a példa kinyomtatja az állapotot a konzolon, de egy jobb implementáció az állapot alapján releváns hibakezelési döntéseket hozna.
Ha nem érdeklik a köztes állapotfrissítések, és csak értesítést szeretne kapni a végleges eredményről, az alábbi példához hasonló kódot használhat:
asyncClient.beginUploadFromUri(...)
.last()
.flatMap(response -> {
if (LongRunningOperationStatus.SUCCESSFULLY_COMPLETED == response.getStatus()) {
return response.getFinalResult();
}
return Mono.error(new IllegalStateException("Polling completed unsuccessfully with status: "+ response.getStatus()));
})
.subscribe(
finalResult -> processFormPages(finalResult),
ex -> countDownLatch.countDown(),
() -> countDownLatch.countDown());
Ebben a kódban a hosszú ideig futó művelet végeredményét hívja meg last()
. Ez a PollerFlux
hívás azt jelzi, hogy várnia kell az összes lekérdezés befejezésére, ekkor a hosszú ideig futó művelet elérte a terminálállapotot, és az eredmény meghatározásához megvizsgálhatja annak állapotát. Ha a lekérdezés azt jelzi, hogy a hosszú ideig futó művelet sikeresen befejeződött, lekérheti a végeredményt, és továbbíthatja azt a fogyasztónak az előfizetési hívásban.
További lépések
Most, hogy már ismeri az Azure SDK for Java régóta futó API-jait, tekintse meg a Proxyk konfigurálása az Azure SDK for Java-ban című témakört, amelyből megtudhatja, hogyan szabhatja testre a HTTP-ügyfelet.