Skip to content

Commit

Permalink
RetryKoraAspect simplified and value class bug fixed
Browse files Browse the repository at this point in the history
  • Loading branch information
GoodforGod committed Aug 1, 2023
1 parent 659ebb9 commit bbeb626
Showing 1 changed file with 28 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ import java.util.concurrent.Future
class RetryKoraAspect(val resolver: Resolver) : KoraAspect {

companion object {
const val ANNOTATION_TYPE: String = "ru.tinkoff.kora.resilient.kora.Retry"
private val MEMBER_RETRY_STATUS = ClassName("ru.tinkoff.kora.resilient.kora.retry", "Retry", "RetryState", "RetryStatus")
private val MEMBER_RETRY_EXCEPTION = MemberName("ru.tinkoff.kora.resilient.kora.retry", "RetryExhaustedException")
const val ANNOTATION_TYPE: String = "ru.tinkoff.kora.resilient.retry.annotation.Retry"
private val MEMBER_RETRY_STATUS = ClassName("ru.tinkoff.kora.resilient.retry", "Retry", "RetryState", "RetryStatus")
private val MEMBER_RETRY_EXCEPTION = MemberName("ru.tinkoff.kora.resilient.retry", "RetryExhaustedException")
private val MEMBER_DELAY = MemberName("kotlinx.coroutines", "delay")
private val MEMBER_TIME = MemberName("kotlin.time.Duration.Companion", "nanoseconds")
private val MEMBER_FLOW = MemberName("kotlinx.coroutines.flow", "flow")
Expand All @@ -51,9 +51,9 @@ class RetryKoraAspect(val resolver: Resolver) : KoraAspect {
val annotation = method.annotations.filter { a -> a.annotationType.resolve().toClassName().canonicalName == ANNOTATION_TYPE }.first()
val retryableName = annotation.arguments.asSequence().filter { arg -> arg.name!!.getShortName() == "value" }.map { arg -> arg.value.toString() }.first()

val managerType = resolver.getClassDeclarationByName("ru.tinkoff.kora.resilient.kora.retry.RetryManager")!!.asType(listOf())
val managerType = resolver.getClassDeclarationByName("ru.tinkoff.kora.resilient.retry.RetryManager")!!.asType(listOf())
val fieldManager = aspectContext.fieldFactory.constructorParam(managerType, listOf())
val retrierType = resolver.getClassDeclarationByName("ru.tinkoff.kora.resilient.kora.retry.Retry")!!.asType(listOf())
val retrierType = resolver.getClassDeclarationByName("ru.tinkoff.kora.resilient.retry.Retry")!!.asType(listOf())
val fieldRetrier = aspectContext.fieldFactory.constructorInitialized(
retrierType,
CodeBlock.of("%L[%S]", fieldManager, retryableName)
Expand All @@ -72,46 +72,39 @@ class RetryKoraAspect(val resolver: Resolver) : KoraAspect {

private fun buildBodySync(method: KSFunctionDeclaration, superCall: String, retryName: String, fieldRetrier: String): CodeBlock {
return CodeBlock.builder()
.add("return %L.asState()", fieldRetrier).indent().add("\n")
.controlFlow(".use { _state ->", fieldRetrier) {
addStatement("val _suppressed = %T<Exception>();", ArrayList::class)
addStatement("lateinit var _result: %T", method.returnType?.resolve()?.toTypeName())
controlFlow("while (true)") {
controlFlow("try") {
add("_result = ").add(buildMethodCall(method, superCall)).add("\n")
addStatement("break")
nextControlFlow("catch (_e: Exception)")
addStatement("val _status = _state.onException(_e)")
controlFlow("when (_status)") {
controlFlow("%T.REJECTED ->", MEMBER_RETRY_STATUS) {
addStatement("_suppressed.forEach { _e.addSuppressed(it) }")
addStatement("throw _e")
}
controlFlow("%T.ACCEPTED ->", MEMBER_RETRY_STATUS) {
addStatement("_suppressed.add(_e)")
if (method.isSuspend()) {
addStatement("%M(_state.delayNanos.%M)", MEMBER_DELAY, MEMBER_TIME)
} else {
addStatement("_state.doDelay()")
}
.add("val _state = %L.asState()", fieldRetrier).add("\n")
.addStatement("val _suppressed = %T<Exception>()", ArrayList::class)
.controlFlow("while (true)") {
controlFlow("try") {
add("return ").add(buildMethodCall(method, superCall)).add("\n")
nextControlFlow("catch (_e: Exception)")
addStatement("val _status = _state.onException(_e)")
controlFlow("when (_status)") {
controlFlow("%T.REJECTED ->", MEMBER_RETRY_STATUS) {
addStatement("_suppressed.forEach { _e.addSuppressed(it) }")
addStatement("throw _e")
}
controlFlow("%T.ACCEPTED ->", MEMBER_RETRY_STATUS) {
addStatement("_suppressed.add(_e)")
if (method.isSuspend()) {
addStatement("%M(_state.delayNanos.%M)", MEMBER_DELAY, MEMBER_TIME)
} else {
addStatement("_state.doDelay()")
}
controlFlow("%T.EXHAUSTED ->", MEMBER_RETRY_STATUS) {
add(
"""
}
controlFlow("%T.EXHAUSTED ->", MEMBER_RETRY_STATUS) {
add(
"""
val _exhaustedException = %M(_state.getAttempts(), _e)
_suppressed.forEach { _e.addSuppressed(it) }
throw _exhaustedException
""".trimIndent(), MEMBER_RETRY_EXCEPTION
)
}
)
}
}
}
addStatement("return@use _result")
}
.unindent()
.add("\n")
.build()
}

Expand Down

0 comments on commit bbeb626

Please sign in to comment.