From ebd4669d2463fc18929b815f76aab598750ed04d Mon Sep 17 00:00:00 2001 From: thug0bin Date: Thu, 5 Mar 2026 13:09:02 +0900 Subject: [PATCH] =?UTF-8?q?fix:=20=EC=A4=91=EB=B3=B5=20=EC=9D=B8=EC=87=84?= =?UTF-8?q?=20race=20condition=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 문제: Set에 추가하는 타이밍이 인쇄 완료 후라서 비동기로 2개 요청이 거의 동시에 들어오면 둘 다 통과 해결: 요청 전에 먼저 Set에 추가 실패/오류 시에만 Set에서 제거 (재시도 가능) --- backend/templates/pmr.html | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/backend/templates/pmr.html b/backend/templates/pmr.html index d6fbb1f..cce6b7f 100644 --- a/backend/templates/pmr.html +++ b/backend/templates/pmr.html @@ -2687,11 +2687,13 @@ return; } - // 2. 중복 인쇄 방지 + // 2. 중복 인쇄 방지 (요청 전에 먼저 체크 & 추가!) if (window.printedSerials.has(preSerial)) { console.log('[AutoPrint] 이미 인쇄됨, 스킵:', preSerial); return; } + // 즉시 Set에 추가 (비동기 race condition 방지) + window.printedSerials.add(preSerial); // 3. 인쇄 진행 try { @@ -2710,20 +2712,22 @@ var data = await response.json(); if (data.success) { - // 인쇄 성공 → Set에 추가 (중복 방지) - window.printedSerials.add(preSerial); console.log('[AutoPrint] ' + now + ' ✅ 인쇄 완료:', preSerial, patientName); window.showToast('🖨️ ' + patientName, 'success'); - - // 5분 후 Set에서 제거 (메모리 관리) - setTimeout(function() { - window.printedSerials.delete(preSerial); - }, 5 * 60 * 1000); } else { + // 실패 시 Set에서 제거 (재시도 가능하도록) + window.printedSerials.delete(preSerial); console.error('[AutoPrint] ' + now + ' ❌ 실패:', preSerial, data.error); window.showToast('인쇄 실패: ' + patientName, 'error'); } + + // 5분 후 Set에서 제거 (메모리 관리) + setTimeout(function() { + window.printedSerials.delete(preSerial); + }, 5 * 60 * 1000); } catch (err) { + // 오류 시 Set에서 제거 + window.printedSerials.delete(preSerial); console.error('[AutoPrint] 오류:', preSerial, err); window.showToast('인쇄 오류', 'error'); }