@@ -18,6 +18,7 @@ import kotlinx.coroutines.CoroutineScope
1818import kotlinx.coroutines.FlowPreview
1919import kotlinx.coroutines.SupervisorJob
2020import kotlinx.coroutines.channels.BufferOverflow
21+ import kotlinx.coroutines.delay
2122import kotlinx.coroutines.flow.Flow
2223import kotlinx.coroutines.flow.MutableSharedFlow
2324import kotlinx.coroutines.flow.SharedFlow
@@ -109,15 +110,38 @@ class RoutineRepositoryImpl @Inject constructor(
109110 if (actualChanges.isEmpty()) return
110111
111112 val syncRequest = RoutineCompletionInfos (routineCompletionInfos = actualChanges)
112- routineRemoteDataSource.syncRoutineCompletion(syncRequest.toDto())
113- .onFailure { error ->
114- _syncError .emit(Unit )
115- val range = routineLocalDataSource.lastFetchRange ? : return @onFailure
116- fetchAndSave(range.first, range.second)
117- .onFailure { rollbackError ->
118- Log .e(" RoutineRepository" , " 롤백 실패: ${rollbackError.message} " )
119- }
120- }
113+ val result = syncWithRetry(syncRequest)
114+
115+ result.onFailure {
116+ _syncError .emit(Unit )
117+ val range = routineLocalDataSource.lastFetchRange ? : return
118+ fetchAndSave(range.first, range.second)
119+ .onFailure { rollbackError ->
120+ Log .e(" RoutineRepository" , " 롤백 실패: ${rollbackError.message} " )
121+ }
122+ }
123+ }
124+
125+ private suspend fun syncWithRetry (
126+ syncRequest : RoutineCompletionInfos ,
127+ maxRetries : Int = 2,
128+ initialDelayMillis : Long = 200L,
129+ ): Result <Unit > {
130+ var delayMillis = initialDelayMillis
131+
132+ repeat(maxRetries + 1 ) { attempt ->
133+ val result = routineRemoteDataSource.syncRoutineCompletion(syncRequest.toDto())
134+
135+ if (result.isSuccess) return result
136+
137+ val isLastAttempt = attempt == maxRetries
138+ if (isLastAttempt) return result
139+
140+ delay(delayMillis)
141+ delayMillis * = 2
142+ }
143+
144+ return Result .failure(IllegalStateException (" Unreachable" ))
121145 }
122146
123147 private suspend fun refreshCache () {
0 commit comments