본문 바로가기

Programming121

[Spring] ApplicationEventPublisher 테스트 (모킹)하기 테스트에서 ApplicationEventPublisher에 대한 모킹을 시도하던 중 여러 시행착오를 겪었다. ApplicationEventPublisher은 일반적으로 모킹이 불가 (e.g. @MockkBean)하며 테스트용 ApplicationEventPublisher 빈을 별도로 만들어 사용하거나 (1), 모킹 포기하고 스프링에서 제시하는 @RecordApplicationEvents로 검증해 보던가(2) 해야 한다. 목차문제 : ApplicationEventPublisher 모킹이 불가하다해결 1. ApplicationEventPublisher 모킹 없이, 테스트하는 방법 (스프링 제안)해결 2. ApplicationEventPublisher를 모킹 하기문제 : ApplicationEventPubli.. 2025. 8. 20.
MySQL 타임존 다루기 데이터베이스에 시각 (날짜) 관련 데이터를 저장하려다 보면 타임존에 대해 고민하게 된다. 국내 한정으로 서비스한다면 크게 고려하지 않는 부분이나, 글로벌 서비스를 고민한다면 필히 타임존을 고려하여 날짜데이터를 다루게 된다. 이번에는 MySQL 데이터베이스를 기준으로 날짜 데이터와 타임존을 어떻게 다룰 수 있는지 알아본다.  목차 MySQL의 날짜와 시간 DATETIME과 TIMESTAMP 다루어보기 MySQL의 날짜와 시간  MySQL의 날짜 타입 DATETIME, TIME : 컬럼 자체에 타임존 정보 없음. 클라이언트가 입력한 값 그 자체를 저장, 반환 TIMESTAMP : UTC로 저장되어 클라이언트에게 반환할 때는 타임존 변환을 거쳐 반환  MySQL이 관리하는 타임존 정보는 아래와 같다. syst.. 2025. 1. 20.
코루틴 스코프에서 스레드 블로킹 해보기 Replace this "Thread.sleep()" call with "delay()".  suspend 함수에서 스레드 블로킹 함수를 호출하면 Replace this "Thread.sleep()" call with "delay()". 과 같은 경고 메시지가 출력된다.  코루틴은 suspend라는 개념을 지원해서 스레드를 블로킹하지 않고 스레드가 다른 코루틴을 실행할 수 있도록 하여 전체 처리량 (throughput)을 높일 수 있다. 따라서 suspend 블록에서 스레드를 블로킹하는 행위나 메서드 호출은 지양하는 것이 좋다. 코루틴 스코프에서 스레드를 블로킹했을 때 동작을 육안으로 확인해 보고자 코드를 작성해 봤다.singleThreadContext : 싱글 스레드 코루틴 context로 제한. 멀티.. 2024. 12. 26.
코루틴 Thread confinement 기법 스레드의 동시 상태변경 문제는 코루틴에서도 동일하게 접할 수 있다.상태공유를 코루틴 간에 무분별하게 하면, thread-safe 하지 못한 코드가 작성될 수 있다.따라서 아래처럼 임계영역은 하나의 스레드 컨텍스트로 제한할 수 있다. 이를 Thread confinement이라 한다.Completed 100000 actions in 474 ms  임계영역에 진입할 때마다 싱글 스레드 컨텍스트로 전환시키는 위와 같은 방법을 fine-grained 방식이라 한다. 다음에 소개할 coarse-grained 방식보다 상대적으로 느리다. Completed 100000 actions in 9 ms  위 방식은 coarse-grained 방식이라 한다. 애초에 임계영역에 진입하기 전에 임계영역을 호출하는 함수 자체를 싱.. 2024. 10. 28.
[Kotlin, Jackson] @JsonCreator 로 enum 값 유연하게 역직렬화 Spirng 개발을 하다 보면 json 직렬화에는 기본으로 jackson 라이브러리를 사용하게 된다. 다른 API 통신, FE 클라이언트와 통신할 때 제일 많이 쓰는 포맷이 json일 듯하다.  Java 에는 enum 클래스를 지원해서 상수값을 편하게 관리할 수 있는데, 대외 통신 시 직렬화 작업을 할 때 그 값이 꼭 Enum에 정의한 값이 아니어도 가능해야할 때가 있다. 예를 들어 enum에는 성별을 MEN, FEMALE로 정의했지만, 호출 단에서는 M, F로 정의해서 보낸다던지 등이다. 따라서 아래처럼 직렬화를 실패하게 된다.   그러나 Jackson 라이브러리는 @JsonCreator 애노테이션을 지원한다. 아래처럼 선언해주면 역직렬화 시 enum을 유연하게 생성할 수 있다.  이제 아래와 같은 테.. 2024. 8. 9.
[Kotlin] runBlocking vs coroutineScope 코루틴은 Structured Concurrency 원칙을 따른다. Structured Concurrency이란 새로운 코루틴은 반드시 CoroutineScope 안에서만 생성 (런치)될 수 있다는 것으로 코루틴의 범위를 제한하는 메커니즘이다. 코루틴의 범위를 제한하고 코루틴의 라이프사이클을 관리하는 인터페이스는 kotlinx.coroutines.CoroutineScope이다.  Scope builder Scope builder란 코루틴의 범위를 나타내는 인터페이스 CorotuineScope을 생성하고, 그 안에서 생성된 모든 코루틴 (자식 코루틴)이 완료될 때까지 기다리는 빌더 함수 (람다)를 말한다. 코루틴 스코프의 최상위 코루틴 (부모 코루틴)은 블로킹된다. 스코프 빌더는 크게 2가지 runBlock.. 2024. 8. 2.