우리 프로그램에서는 await
으로 작업 재시도 패턴을 구현하려고합니다.기다려온 비동기 메소드 이전 재시도 페이로드 유지
우리의 주요한 문제는 우리의 방법이 후속 시도에서 첫 번째 재시도 페이로드를 유지한다는 것입니다.
async retryTaskUntilExpectedValue({
task,
expectedValue,
messageOnError = 'Max retry number reached without expected result',
maxRetries = 10,
timeout = 10,
spinner = null
}) {
let printFn = console.log;
if (spinner !== null) {
printFn = spinner.text;
}
// Proceed retries
for (let i = 1; i <= maxRetries; i++) {
try {
let result = await task;
console.log(result); // Always display same result: {"state": "upgrading"} even if curling returns {"state": "upgraded"} after about 2 retries
result = JSON.parse(result).state;
if (result === expectedValue) {
return Promise.resolve(result);
} else if (i <= maxRetries) {
printFn(`Result "${result}" differs from expected value "${expectedValue}"`);
await wait(1000);
printFn(`Waiting ${timeout}s before retry`);
await wait(timeout * 1000);
printFn(`Retrying (${i})`);
continue;
} else {
return Promise.reject(`ERROR: ${messageOnError}`);
}
} catch (err) {
return Promise.reject(`ERROR: Unexpected error while running task`);
}
}
};
그리고 우리의 CLI에서 사용 : 여기
가 재시도 방법 우리의 경우checkUpgrade(url) {
return retryTaskUntilExpectedValue({
task: this.makeHttpRequest('GET', url),
expectedValue: 'upgraded'
});
}
작업이 우리의 백엔드 데이터베이스에서 상태를 반환하는 HTTP 요청입니다.
모델은 간단합니다 : { "state": "upgrading" }
그런 다음 백엔드 작업이 완료되면 { "state": "upgraded"}
을 반환합니다.
작업을 처리하는 데 약간의 시간이 걸립니다 (약 20 초). 우리의 테스트에서이 문제가 발생했습니다
- 먼저 전화 :
upgrading
- 첫 번째 재시도 : 그 후
upgrading
- 을 손으로 직접 REST API를 컬링에 의해, 나는
upgraded status
- 다른 모든 시도를 얻을 수 CLI를에 : 그래서 우리가 구축 CLI에서
upgrading
, 우리는 10 시간 결과를 가지고 : Result "upgrading" differs from expected value "upgraded"
이후 재 시도에서 let response = await task;
이 재 시도 할 때마다 작업 메서드를 호출하지 않는 것 같습니다. 실제로 실제 전화가 걸려온다면, 우리가 컬을 통해 얻을 수 있기 때문에 업그레이드 된 상태를 확실히 검색 할 수 있습니다.
실제로 await task;
을 호출 작업 메서드를 트리거하고 첫 번째 호출에서 결과를 유지하지 않으려면 어떻게해야합니까?
'task'가 약속이라면, 한번만 해결하거나 거절 할 것이며, 이후에'await'는 첫 번째 해결이나 거절을 참조 할 것입니다. –
"*'let response = await task;처럼 보입니다. 이후 재시도에서 재 시도 할 때마다 작업 메소드를 호출하지 않습니다. *"- 물론 아닙니다. 'task'는 메소드가 아니며, 약속이고, 그것들은 단일 값으로 한 번만 해결됩니다. 대신에 함수를 전달하고'task()'를 사용하여 함수를 호출하면됩니다. – Bergi
Bergi에게 감사드립니다. 처음에는 그것을 얻지 못했습니다. 나는 지금 더 잘 이해한다. – BlackHoleGalaxy