Wzorzec ponawiania oczekiwania
W niektórych sytuacjach zachowanie źródła danych nie jest zgodne z oczekiwaniami domyślnej obsługi kodu HTTP w dodatku Power Query. W poniższych przykładach pokazano, jak obejść tę sytuację.
W tym scenariuszu będziesz pracować z interfejsem API REST, który od czasu do czasu zwraca kod stanu 500 wskazujący wewnętrzny błąd serwera. W tych przypadkach można poczekać kilka sekund i ponowić próbę, potencjalnie kilka razy przed rezygnacją.
Jeśli Web.Contents
zostanie wyświetlona odpowiedź kodu stanu 500, zostanie ona domyślnie wyrzucona DataSource.Error
. To zachowanie można zastąpić, podając listę kodów jako opcjonalny argument dla Web.Contents
elementu :
response = Web.Contents(url, [ManualStatusHandling={404, 500}])
Określając kody stanu w ten sposób, dodatek Power Query będzie nadal przetwarzać odpowiedź internetową w zwykły sposób. Jednak normalne przetwarzanie odpowiedzi często nie jest odpowiednie w tych przypadkach. Musisz zrozumieć, że otrzymano nietypowy kod odpowiedzi i wykonać specjalną logikę do jej obsługi. Aby określić kod odpowiedzi zwrócony z usługi internetowej, możesz uzyskać do niego dostęp z rekordu meta
, który towarzyszy odpowiedzi:
responseCode = Value.Metadata(response)[Response.Status]
Na podstawie tego, czy responseCode
jest to 200, czy 500, możesz przetworzyć wynik w normalny sposób lub postępować zgodnie z logiką oczekiwania ponawiania prób, którą określisz w następnej sekcji.
Dodatek Power Query ma lokalną pamięć podręczną, która przechowuje wyniki poprzednich wywołań do pliku Web.Contents. Podczas sondowania tego samego adresu URL nowej odpowiedzi lub ponawiania próby po wystąpieniu stanu błędu należy upewnić się, że zapytanie ignoruje wszystkie buforowane wyniki. Można to zrobić, włączając IsRetry
opcję w wywołaniu Web.Contents
funkcji. W tym przykładzie ustawimy wartość IsRetry
na po true
pierwszej iteracji Value.WaitFor
pętli.
Value.WaitFor()
jest standardową funkcją pomocnika, która zwykle może być używana bez modyfikacji. Działa przez utworzenie listy ponownych prób.
Zawiera to zadanie, które ma być (prawdopodobnie) ponawiane. Jest reprezentowana jako funkcja, aby można było użyć numeru iteracji w logice producer
. Oczekiwane zachowanie polega na tym, że producer
zostanie zwrócone null
, jeśli ponowna próba zostanie określona jako niezbędna. Jeśli coś innego niż null
jest zwracane przez producer
wartość , ta wartość jest z kolei zwracana przez Value.WaitFor
.
Zawiera logikę do wykonania między ponownych prób. Jest reprezentowana jako funkcja, aby można było użyć numeru iteracji w logice delay
. Oczekiwane zachowanie polega na delay
zwracaniu czasu trwania.
Maksymalną liczbę ponownych prób można ustawić, podając liczbę argumentu count
.
W poniższym przykładzie pokazano, jak ManualStatusHandling
i Value.WaitFor
za pomocą którego można zaimplementować opóźnione ponowienie próby w przypadku odpowiedzi 500. Czas oczekiwania między ponownymi próbami dwukrotnie z każdą próbą, z maksymalnie pięcioma ponownymi próbami.
let
waitForResult = Value.WaitFor(
(iteration) =>
let
result = Web.Contents(url, [ManualStatusHandling = {500}, IsRetry = iteration > 0]),
status = Value.Metadata(result)[Response.Status],
actualResult = if status = 500 then null else result
in
actualResult,
(iteration) => #duration(0, 0, 0, Number.Power(2, iteration)),
5)
in
if waitForResult = null then
error "Value.WaitFor() Failed after multiple retry attempts"
else
waitForResult