시배's Android

Hi Jack Mocker | 개선기 (4) feat.out of order 본문

Android/Hi Jack Mocker

Hi Jack Mocker | 개선기 (4) feat.out of order

si8ae 2024. 7. 13. 19:55

Hi Jack Mocker란?

 

GitHub - koreatlwls/Hi-Jack-Mocker: Hi-Jack-Mocker is a project that leverages OkHttp3's interceptor to intercept and modify net

Hi-Jack-Mocker is a project that leverages OkHttp3's interceptor to intercept and modify network requests and responses, allowing you to verify the UI easily. - koreatlwls/Hi-Jack-Mocker

github.com

Hi Jack Mocker는 비개발자도 UI 엣지 케이스를 쉽게 테스트할 수 있도록 돕는 라이브러리입니다. 이 프로젝트는 OkHttp3 인터셉터를 활용하여 네트워크 요청과 응답을 가로채고 수정할 수 있게 합니다. 이를 통해 개발자뿐만 아니라 다양한 사용자들이 다양한 시나리오를 테스트할 수 있게 합니다.

 

Channel의 동시 네트워크 요청 처리 순서 문제

동시에 여러 네트워크 요청을 처리하는 데 어려움이 있었습니다. 처음에는 Kotlin의 채널을 사용하여 모킹된 네트워크 응답을 인터셉터에 전달했습니다. 하지만 채널은 여러 인터셉터 간에 메시지를 공정하게 분배하기 때문에 응답이 순서대로 전달되지 않는 문제가 발생했습니다. 이로 인해 A 데이터를 받아야 하는 요청이 B 데이터를 받는 등의 예기치 않은 문제가 발생했습니다.

future.complete(interceptorManager.receiveWithResultChannel())

suspend fun receiveWithResultChannel(): Response {
	if (resultChannel.isClosedForReceive) {
		resultChannel = Channel(UNLIMITED)
    }

    return resultChannel.receive()
}

위 코드에 보다시피 아무런 조건 없이 receive()를 하다 보니 문제가 발생했습니다.

해결책

이 문제를 해결하기 위해 다수의 구독자가 있는 경우에 적합한 Kotlin의 SharedFlow로 전환했습니다. 추가로 UUID를 도입하여 각 인터셉터가 올바른 응답을 받을 수 있도록 했습니다. 구현 방법은 다음과 같습니다.

 

  • 각 요청에 대해 UUID 생성: 각 요청-응답 쌍을 고유하게 식별할 수 있도록 합니다.
  • UUID와 함께 이벤트 전송: 인터셉터가 이벤트를 UUID와 함께 전송합니다.
  • UUID로 응답 필터링: 응답을 받을 때 UUID로 필터링하여 올바른 응답을 받도록 합니다.
override fun intercept(chain: Interceptor.Chain): Response = runBlocking {
    var response = chain.proceed(chain.request())

    if (hjmDataStore.getHjmMode()) {
        val uuid = UUID.randomUUID().toString()
        interceptorManager.sendEventAtInterceptorEvent(uuid, response)

        startHjmActivityIfNeeded()

        response = interceptorManager.resultEvent.filter { it.first == uuid }.first().second
    }

    return@runBlocking response
}

 

이를 통해 각 요청이 적절한 응답을 받도록 보장할 수 있었습니다.