TR 응답 블록 파싱 예외로 데이터가 조용히 유실되던 문제 수정 - #2
Open
qudgus3822 wants to merge 2 commits into
Open
Conversation
- 파싱 실패 해결 : 체결가가 float(소수)로 넘어오는걸 파싱하지 못함 (분할 매수의 경우)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
📝 요약
nLen % struct_size != 0) ERROR 로그를 남깁니다.실계좌에서 주문/체결 조회(s8180) 결과가 일부만 들어오는 것을 추적하다 발견했습니다.
1. 파싱 예외 = 블록 증발 (가장 심각)
Received._auto_parse()에서 난 예외는 위로 올라가다WMCAAgent._wnd_proc()의except Exception에서 삼켜집니다. 윈도우 프로시저는 예외를 밖으로 내보내면 안 되니 삼키는 것 자체는 맞는데, 문제는 삼킨 뒤에 벌어지는 일입니다.message_queue.put()이 실행되지 않으므로receive_events()를 도는 호출부는 그 블록을 영영 보지 못합니다. 호출부 입장에선 "데이터가 원래 없었다"와 구분할 방법이 없습니다. 로그는메시지 처리 오류한 줄뿐이라, 조회가 반쪽만 성공한 건지 정말 결과가 없는 건지 알 수 없었습니다.2. 레코드 경계가 어긋나면 조용히 잘리고, 남은 행은 밀려 읽힘
_parse_array_internal()은 행 수를occurs_count = nLen // struct_size로 구합니다. 구조체 정의가 서버가 보내는 레코드 길이와 1바이트라도 다르면:쓰레기 행은 상위 필터(종목코드 없음 / 수량 0 등)에 걸려 자연스럽게 사라지므로, 겉으로는 그냥 "일부만 조회됐다"로만 보입니다. 원인을 짚을 단서가 전혀 없습니다.
3. 한 행이 깨지면 블록 전체가 날아감
배열 파싱 루프에 방어가 없어, 한 행에서 예외가 나면 그 블록 전체(TR에 따라 반복 최대 15~20건)가 함께 사라졌습니다.
💡 해결 방안 및 근거
structures/common.py_auto_parse(): 파싱을try/except로 감싸고, 실패하면szData를 원본 bytes 그대로 반환합니다.isinstance(block.szData, bytes)로 방어하고 있습니다. 그 경로를 재사용하므로 인터페이스 변화 없이 "조용한 증발"만 "눈에 보이는 경고"로 바뀝니다._parse_array_internal(): 행 단위try/except로 부분 성공을 허용합니다. 한 행이 깨졌다고 멀쩡한 나머지 행까지 버릴 이유가 없습니다._parse_array_internal():nLen % struct_size != 0이면 ERROR 로그를 남깁니다. 구조체 정의와 서버 스펙이 어긋났다는 유일한 단서라서 반드시 남겨야 합니다.wmca_agent.py_wnd_proc()의 예외 로그에 "이 이벤트는 큐에 들어가지 못하고 유실됨"과wparam을 함께 남깁니다. 이 줄이 찍혔다는 건 응답 일부가 유실됐다는 뜻인데, 기존 메시지로는 그 사실이 드러나지 않았습니다.호환성
정상 경로의 동작은 그대로입니다. 예외가 나던 경로만 "증발" 대신 "bytes 반환 + 로그"로 바뀝니다. 공개 API 시그니처 변경 없음.
✅ 리뷰 체크리스트