문제
TaskRunner.run()의 .then() 콜백에서 fulfilled 케이스만 _isDone = true를 처리하고 있어, reject 시 _isDone이 영원히 false로 남음
return this._promise = this.f().then(res => {
this._isDone = true;
return res;
});
영향 범위
code_6_27_28의 TaskPool클래스
runAll(): errorHandle이 Promise.reject(err)를 반환하므로 await에서 즉시 throw → 루프 탈출. 문제 없음.
runAllSettled(): errorHandle이 () => undefined로 에러를 흡수하므로 루프가 계속 진행. 아래 문제 발생.
발생 메커니즘 (runAllSettled)
Promise.race()가 rejected promise로 settle → .catch()가 에러 흡수
pool.findIndex(task => task.isDone) → 에러난 task는 isDone === false이므로 매칭 안 됨
findIndex가 -1 반환 → splice(-1, 1)이 마지막 원소를 제거 (엉뚱한 정상 task 제거)
- 에러난 task는 pool에 잔류
- 다음 루프에서
task.run() 호출 → this._promise가 이미 rejected 상태로 캐싱돼있으므로 즉시 reject
- 1번으로 복귀
Iterator 종류에 따른 결과
무한 iterator인 경우: rejected task가 pool에 영구 잔류하면서 매 iteration마다 즉시 reject → 6번에서 1번 복귀가 무한 반복. 무한루프.
유한 iterator인 경우: splice(-1, 1)이 매번 잘못된 task를 하나씩 제거하므로 iterator 소진 후 결국 루프를 탈출하긴 하지만, 다음 문제가 발생
- 정상 task가 pool에서 조기 제거되어 실행됨
따라서, rejected task가 즉시 settle하면서 iterator를 의도보다 훨씬 빠르게 소진 → poolSize 기반 동시성 제어가 깨짐
수정 제안
TaskRunner.run()에서 reject 케이스도 _isDone = true 처리:
return this._promise = this.f().then(
res => { this._isDone = true; return res; },
err => { this._isDone = true; throw err; }
);
좋은 컨텐츠 공유해주셔서 감사합니다. 많이 배우고 있습니다. 감사합니다.
문제
TaskRunner.run()의.then()콜백에서 fulfilled 케이스만_isDone = true를 처리하고 있어, reject 시_isDone이 영원히false로 남음영향 범위
code_6_27_28의 TaskPool클래스
runAll(): errorHandle이Promise.reject(err)를 반환하므로await에서 즉시 throw → 루프 탈출. 문제 없음.runAllSettled(): errorHandle이() => undefined로 에러를 흡수하므로 루프가 계속 진행. 아래 문제 발생.발생 메커니즘 (runAllSettled)
Promise.race()가 rejected promise로 settle →.catch()가 에러 흡수pool.findIndex(task => task.isDone)→ 에러난 task는isDone === false이므로 매칭 안 됨findIndex가-1반환 →splice(-1, 1)이 마지막 원소를 제거 (엉뚱한 정상 task 제거)task.run()호출 →this._promise가 이미 rejected 상태로 캐싱돼있으므로 즉시 rejectIterator 종류에 따른 결과
무한 iterator인 경우: rejected task가 pool에 영구 잔류하면서 매 iteration마다 즉시 reject → 6번에서 1번 복귀가 무한 반복. 무한루프.
유한 iterator인 경우:
splice(-1, 1)이 매번 잘못된 task를 하나씩 제거하므로 iterator 소진 후 결국 루프를 탈출하긴 하지만, 다음 문제가 발생따라서, rejected task가 즉시 settle하면서 iterator를 의도보다 훨씬 빠르게 소진 → poolSize 기반 동시성 제어가 깨짐
수정 제안
TaskRunner.run()에서 reject 케이스도_isDone = true처리:좋은 컨텐츠 공유해주셔서 감사합니다. 많이 배우고 있습니다. 감사합니다.