@@ -11,9 +11,11 @@ import com.dobby.backend.domain.model.Verification
1111import com.dobby.backend.infrastructure.database.entity.enums.VerificationStatus
1212import com.dobby.backend.util.EmailUtils
1313import kotlinx.coroutines.CoroutineScope
14+ import kotlinx.coroutines.delay
1415import kotlinx.coroutines.launch
15- import kotlinx.coroutines.withContext
16- import org.springframework.stereotype.Component
16+ import org.slf4j.LoggerFactory
17+ import kotlin.math.pow
18+ import kotlin.random.Random
1719
1820class SendEmailCodeUseCase (
1921 private val verificationGateway : VerificationGateway ,
@@ -75,9 +77,34 @@ class SendEmailCodeUseCase(
7577 }
7678 }
7779
80+ private val logger = LoggerFactory .getLogger(SendEmailCodeUseCase ::class .java)
81+
7882 private suspend fun sendVerificationEmail (univEmail : String , code : String ) {
7983 val content = EMAIL_CONTENT_TEMPLATE .format(code)
80- emailGateway.sendEmail(univEmail, EMAIL_SUBJECT , content)
84+ val maxRetries = 3
85+
86+ var attempt = 1
87+ while (attempt <= maxRetries) {
88+ try {
89+ emailGateway.sendEmail(univEmail, EMAIL_SUBJECT , content)
90+ return
91+ } catch (ex: Exception ) {
92+ attempt + = 1
93+ if (attempt >= maxRetries) {
94+ logger.error(" Failed to send email verification to $univEmail after $maxRetries attempts." , ex)
95+ throw ex
96+ }
97+ val backOffTime = calculateBackOff(attempt)
98+ logger.warn(" Retrying to sending email... Attempt: $attempt , Waiting: ${backOffTime} ms" )
99+ delay(backOffTime)
100+ }
101+ }
102+ }
103+
104+ private fun calculateBackOff (attempt : Int ): Long {
105+ val defaultDelay = 1000L
106+ val maxJitter = 500L
107+ return defaultDelay * (2.0 .pow(attempt)).toLong() + Random .nextLong(0 , maxJitter)
81108 }
82109
83110 companion object {
0 commit comments