Skip to content

[Feat] TimerSyncWorker 추가 #588

Description

@edv-Shin

어떤 기능인가요?

전송 대기 상태의 타이머를 서버로 올리는 워커를 추가합니다. 앱이 종료되거나 기기가 재부팅돼도 연결 조건이 충족되면 실행됩니다.

지금 서버로 올리는 경로가 아예 없습니다. ApiService.postSimpleTimer, patchSimpleTimer, deleteSimpleTimer는 선언만 있고 프로덕션 호출부가 0이며 TimerRepositoryImpl은 로컬만 씁니다. TimerLocalDataSource.getPendingSimpleTimers()도 테스트만 소비합니다. 그래서 오프라인에서 만든 타이머가 로컬에만 쌓이고, 서버 목록 반영이 serverId = null 행을 건드리지 않으므로 개수가 단조 증가합니다. 사용자 기기에서 심플 타이머가 6개를 넘어 화면이 겹친 원인입니다.

  • FcmTokenSyncWorkerFcmTokenSyncScheduler 패턴을 그대로 씁니다. Hilt Worker 배선(Configuration.Provider, HiltWorkerFactory)은 이미 있습니다
  • 연결 상태 제약과 지수 백오프, 유니크 작업으로 예약해 같은 작업이 동시에 두 번 돌지 않게 합니다
  • 재시도 판단은 안드로이드 의존성이 없는 정책 오브젝트로 분리해 단위 테스트로 검증합니다. FcmTokenSyncPolicy와 같은 방식입니다
  • 작업 입력에 memberId를 넣고 각 네트워크 호출 전 현재 세션과 일치하는지 확인합니다. 다르면 아무것도 보내지 않고 성공으로 종료합니다

처리 순서를 생성 → 수정 → 삭제로 고정합니다. 삭제를 먼저 처리하면 서버 개수가 일시적으로 비정상이 되는 창이 생깁니다. ExerciseSyncWorker 설계도 같은 이유로 순서를 고정했습니다.

삭제가 판정에서 이깁니다. 이미 삭제된 타이머에 수정을 보내면 서버가 "삭제됨"을 응답합니다. 그때는 로컬 행을 지웁니다. 오프라인에서 한 수정은 버립니다. 이 규칙 덕분에 조회 응답에 삭제 기록이 없어도 기기 간에 수렴합니다.

개수 상한은 서버가 수용 후 보정합니다. 상한 초과 생성 요청도 서버가 받고 편집 시각 최신순으로 상한만큼만 남깁니다. 워커는 거부를 받지 않으므로 개수 때문에 실패하는 경로가 없습니다. 밀려난 행은 다음 목록 조회에서 로컬에서도 사라집니다.

서버 작업(api-server #574, #575)이 prod에 배포된 뒤에 머지합니다. 그 전에 열면 중복 생성과 덮어쓰기가 실제로 일어납니다. #602(강제 로그아웃 시 대기 행 보존)가 선행입니다. 대기 행을 남기기로 했으므로 워커는 재로그인 후 이어서 전송해야 합니다.

작업 상세 내용

  • TimerSyncWorker와 스케줄러 인터페이스 추가 (연결 제약, 지수 백오프, 유니크 작업)
  • 재시도 상한 정책을 안드로이드 의존성 없는 오브젝트로 분리
  • 처리 순서 고정: 생성 → 수정 → 삭제
  • 작업 입력에 memberId를 넣고 호출 전 현재 세션과 일치 확인. 다르면 전송 없이 성공 종료
  • 생성 성공 시 serverId 기록 후 동기화 완료 전이
  • 재시도에 같은 createRequestId 사용
  • 수정과 삭제 재시도에 전송 중 스냅샷의 editIdeditedAt 사용
  • 전송 중 스냅샷 컬럼 추가 (inFlightEditId 등). #586에서 이 이슈로 미뤘습니다
  • 전송 중에 사용자가 또 저장하면 대기 식별자만 새로 발급하고 전송 중 칸은 건드리지 않음
  • 409 수신 시 로컬을 서버 값으로 갱신 후 동기화 완료 처리
  • "삭제됨" 응답 수신 시 로컬 행 삭제
  • ClearSessionUseCase에 예약 취소 연결. FcmTokenSyncScheduler 패턴
  • 반복 실패 행 처리 규칙. lastSyncError 기록
  • 미사용 코드 정리. TimerDao.countSimpleTimersTimerLocalDataSource.countSimpleTimers는 호출부가 없습니다
  • 전송 작업 테스트 (대기에서 완료까지 전이, 실패 시 재시도, 응답 유실 재시도의 동일 식별자, 처리 순서, 계정 불일치 시 미전송)
  • 오프라인 생성 3건 후 연결 복구 시 서버에 정확히 3건, 중복 없음 수동 확인
  • 오프라인에서 생성 후 수정 후 삭제, 연결 복구 시 서버에 아무것도 남지 않는지 수동 확인
  • 기기 A에서 삭제한 타이머를 기기 B가 오프라인에서 수정한 뒤 연결 복구 시 B에서도 사라지는지 수동 확인

참고할만한 자료(선택)

오프라인 기능 지원 설계 문서의 구성 요소 3(TimerSyncWorker), 설계 규칙 D7(모든 쓰기 요청에 요청 식별자), D8(전송은 Worker가 맡음), 위험 요소 2(응답 유실 시 중복 생성)와 4(성공 후 응답 유실 재시도가 409로 오판)가 기준입니다.

선행 이슈는 #586(저장층, 머지), #587(읽기·쓰기 배선), #602(강제 로그아웃 시 대기 행 보존)입니다. api-server #574와 #575의 prod 배포가 머지 조건입니다.

RoomSessionDataCleaner.clearAll()database.clearAllTables()를 부르므로 #586에서 추가한 타이머 테이블은 세션 정리에 이미 포함됩니다. 이 이슈에서 추가할 것은 워커 취소입니다.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions