Skip to content

fix: TypeLoaderUsingMetadata 타입 캐시 동시성 안전성 개선#255

Open
z3rotig4r wants to merge 1 commit into
eGovFramework:mainfrom
z3rotig4r:fix/typeloader-concurrent-map
Open

fix: TypeLoaderUsingMetadata 타입 캐시 동시성 안전성 개선#255
z3rotig4r wants to merge 1 commit into
eGovFramework:mainfrom
z3rotig4r:fix/typeloader-concurrent-map

Conversation

@z3rotig4r

Copy link
Copy Markdown
Contributor

변경 이유

TypeLoaderUsingMetadata.typePool이 동기화 없는 HashMap입니다. 이 클래스는 싱글톤 빈으로 주입되고(TypeLoader 인터페이스의 public getType()), 웹서비스 연계 처리 등에서 여러 스레드가 동시에 호출합니다.

getType()은 캐시를 typePool.get(id)로 검사한 뒤 로딩 후 typePool.put(id, type)로 갱신합니다. 콜드 캐시에 동시 진입하면:

  • HashMap에 대한 동시 put으로 맵 손상(리사이즈 중 무한 루프·엔트리 유실)이 발생할 수 있고,
  • 각 스레드가 자신이 만든 인스턴스를 그대로 반환해 동일 타입에 대해 서로 다른 인스턴스가 돌아갑니다.

변경 내용

  • typePoolConcurrentHashMap으로 변경합니다.
  • 로딩 후 putIfAbsent로 먼저 등록된 인스턴스를 정본으로 반환해, 동시 호출에도 동일 타입에 대해 일관된 인스턴스를 제공합니다.

단일 스레드 동작은 동일합니다(putIfAbsent가 null을 반환하므로 새로 만든 인스턴스를 반환).

테스트 방법

TypeLoaderUsingMetadataConcurrencyTest: 16개 스레드가 동일 타입(boolean[])을 동시에 getType 호출했을 때 예외 없이 모두 같은 정본 인스턴스를 반환함을 검증합니다. (변경 전 코드에서는 스레드마다 다른 인스턴스를 반환해 이 단정이 실패함을 확인했습니다.) 모듈 전체 테스트(67건) 회귀를 확인했습니다.

영향 범위

타입 캐시 맵의 동시성 처리만 변경하며 반환 타입의 의미는 동일합니다. 머지된 동시성 개선(StringTimestampTypeHandler·AuthorityResourceMetadata)과 같은 맥락입니다.

typePool이 동기화 없는 HashMap이라, 싱글톤으로 주입된 TypeLoader의 getType()을
여러 스레드가 콜드 캐시에서 동시에 호출하면 검사(get)와 갱신(put) 사이 경합으로
맵 손상(리사이즈 무한 루프·엔트리 유실)이나 스레드마다 서로 다른 인스턴스가
반환될 수 있었다. typePool을 ConcurrentHashMap으로 바꾸고, load 후 putIfAbsent로
먼저 등록된 인스턴스를 정본으로 반환해 동시 호출에도 일관된 타입을 제공한다.

16스레드 동시 getType 단위테스트로 예외 없이 동일 정본 인스턴스 반환을 검증했다.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant