fix: recreate Redis stream receiver after listener failure - #157
fix: recreate Redis stream receiver after listener failure#157oosuhada wants to merge 99 commits into
Conversation
* build: gradle 의존을 설정하고 기본 라이브러리를 추가한다 * build: Netx-IDL 을 서브모듈로 추가한다 * docs: Readme.md 를 꾸민다 * build: jvmTarget을 21에서 17로 변경한다 * ci: assigner, tester, type-labeler 를 추가한다 * refactor: protobuf idl 경로를 ./api-spec에서 ./idl 로 변경한다
* feat: transaction api 를 정의한다 * feat: 실제 동작이 구현되어있는 engine 레이어를 정의하고 동작을 구현한다 * feat: Transaction의 상태별로 event 를 발행하게 한다 * refactor: Transaction start 혹은 join일때, transaction을 구독하도록한다 * feat: redis-stream 기반의 transation-manager 를 구현한다 * feat: AutoConfig 를 정의한다 * fix: TransactionIdGenerator에서 존재하지 않는 클래스 구현하고 있는 버그 수정 * refactor: transaction id 를 node-id 기반으로 생성하도록 수정 * refactor: 자동구성이 어노테이션 기반으로 동작 가능하도록 수정한다 * refactor: TransactionEvent들에 어떤 서버에서 발행되었는지 확인할 수 있도록 nodeName 필드를 추가한다 * refactor: TransactionDispatcher를 추상화시키고, 로직을 따르도록 강제화 한다 * fix: RedisStream 구독을 poll 방식이 아닌 subscirbe 방식으로 수정하고 처음부터 모든 데이터를 읽어오도록 한다 * refactor: replay 필드가 rollback 이벤트에만 존재하도록 수정한다 * refactor: exists 메소드 구현을 engine레이어로 올리고, context를 세팅한다 * refactor: transformTransactionId 이름을 mapTransactionId로 변경한다 * test: RedisStreamTransactionManager의 Test를 작성한다 * build: jitpack 배포 플러그인을 설정한다 * docs: 사용법과 다운로드 방법을 작성한다 * docs: 분산 트랜잭션 작동과정 gif를 추가한다
* build: jitpack 배포구성을 설정한다 * build: sonarProjectKey가 잘못 설정 되어있는버그수정 * build: sonarProjectKey 수정
* feat: Netx가 undo 상태를 따로 관리하도록 수정한다 * refactor: 2개로 분리된 AutoConfigure 어노테이션을 하나로 합친다
* refactor: UndoManager를 삭제하고, 메시지큐에서 전부 관리하도록 수정한다 * feat: 처리하지 못한 고아 트랜잭션을 찾아서 처리하는 recovery기능을 추가한다 * fix: RedisRetrySupporter가 Pending 상태의 메시지를 파싱하지 못하는 버그를 수정한다 * feat: pending되었지만, ack되지않은 트랜잭션을 찾아서 처리하는 기능을 추가한다 * build: netx-idl 버전 최신화
* fix: interval 과정중 에러 방출시 무시하고 계속 interval 되도록 수정한다 * refactor: 로컬 로직이 실패하면 분산트랜잭션도 ack되지 않도록 수정한다 * test: TransactionHandlerAssertions을 사용하고 항상 초기화하도록 수정한다
* test: Netx client 부하테스트를 작성한다 * perf: netx redis-stream 구현채가 하나의 커넥션으로 트랜잭션을 수신할 수 있도록 수정한다
* 자신이 발행한 transaction을 찾지 못하는 버그를 수정한다 * refactor: 사용하지 않는 메소드를 삭제한다
* feat: sync 호출을 지원한다 * docs: README에 동기 지원 방식을 추가한다 * docs: README code의 컨벤션 오류를 수정한다 * docs: 분산트랜잭션 동작과정 사진을 330 -> 365 로 증가시킨다 * docs: 분산트랜잭션 사진을 365 -> 360 으로 변경한다 * �docs: version update 0.1.9 to 0.2.0
…evxb#42) * perf: supprot Backpressure and & auto restart transaciton listener * docs: netx version 0.2.0 to 0.2.1 * perf: boundElastic 과 parallel 사용을 수정한다
* refactor: replace word transaction to saga * build: netx version 0.3.8 to 0.3.9
* refactor: Access modifier public to internal * refactor: OrchestratorChain's return type to api.OrchestratorFactory
* feat: Get orchestratorFactory method to api.OrchestratorFactory * docs: Autowired OrchestratorFactory to Instance OrchestratorFactory
* refactor: sagaManager's sync... method to ...sync * docs: Write dokka doc
* build: Chaing publish repository jitpack to maven central * docs: Download url to maven central and add test section * docs: update link and test image * docs: fixed inner tps link * docs: update option and description of features * docs: add blocking supports word on description
…vxb#132) * fix: Primary to reactiveRedisTemplate and reactiveRedisConnection * docs: version 0.4.0 to 0.4.1
* refactor: Catch toOrchestrateEvent's exception * refactor: version 0.4.1 to 0.4.2
* test: Orchestrator Result test 를 추가한다 * refactor: Orchestrator도중에 예외가 발생하면, 이전 chain부터 rollback이 수행되도록 한다 * docs: Readme.md에 rollback 발생 순서를 수정한다 * build: version을 0.4.2에서 0.4.3으로 올린다
* refactor: abstract saga listener를 graceful하게 종료한다 * build: version to 0.4.3 -> 0.4.4-beta-1
…xb#143) * fix: miss action in decodeResultOrThrow when using TypeReference * docs: version upgrade
* refactor: JsonCodec fail on Unknown property * refactor: JsonCodec Fail On Missing properties * docs: version 0.4.5 0> 0.4.6
* fix: Infinite loading phenomenon when error encoding fails * docs: version 0.4.7 -> 0.4.8
* feat: Rollback Consumer Dead Letter * docs: add dead letter description * Update README.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…evxb#155) * fix: Restrict Orchestrator process only messages from its own group * docs: version up 0.4.9 -> 0.5.0
|
@devxb 확인 부탁드립니다.
이 PR의 0.5.1을 사용하도록 @devxb Could you please take a look when you have a chance? The production issue tracked in I also prepared the |
3b73875 to
0ec2c96
Compare
요약
StreamReceiver인스턴스를 재사용하던 동작을 수정했습니다.StreamReceiver를 생성하도록 변경해, 네트워크/연결 오류 이후 기존 receiver가 stale/terminal 상태에 남아도 listener가 복구될 수 있도록 했습니다.0.5.0→0.5.1로 올렸습니다.배경
AbstractSagaListener는 listener가 종료되면subscribeStream()을 다시 호출해 자동 복구를 시도합니다. 하지만RedisStreamSagaListener는StreamReceiver를 프로퍼티로 한 번만 생성해 두고 있었기 때문에, receiver 자체가 연결 오류 이후 복구 불가능한 상태가 되면 재구독에서도 같은 인스턴스를 계속 사용하게 됩니다.이 동작은
git-goods/gitanimals#501에서 관찰된 장시간 실행 API의 Saga timeout 증상을 조사하면서 확인했습니다. 해당 서비스에서는 일반 read API는 정상인 상태에서 Saga 기반 write 요청만 기본 10초/100초 결과 timeout으로 실패하고 있었습니다.테스트
./gradlew test --tests 'org.rooftop.netx.redis.RedisStreamSagaListenerTest' --console=plaingitanimals-api에 연결해 아래 Saga 회귀 테스트를 각각 깨끗한 Redis에서 검증했습니다.GotchaFacadeV3TestRegisterProductFacadeTestBuyProductFacadeTestSummary
StreamReceiverwhenever the listener subscribes again after an error0.5.0to0.5.1, following the existing release patternBackground
AbstractSagaListeneralready attempts to recover by callingsubscribeStream()again after termination. However,RedisStreamSagaListenerpreviously kept oneStreamReceiverinstance for its entire lifetime. If that receiver itself becomes stale or terminal after a connection failure, resubscribing keeps reusing the same broken receiver.This behavior was identified while investigating
git-goods/gitanimals#501, where long-running API instances continued serving reads while Saga-based writes consistently timed out waiting for results.Test
./gradlew test --tests 'org.rooftop.netx.redis.RedisStreamSagaListenerTest' --console=plaingitanimals-apiSaga tests with clean Redis instances:GotchaFacadeV3TestRegisterProductFacadeTestBuyProductFacadeTest