-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor: 로컬 로직이 실패하면 분산트랜잭션도 ack되지 않도록 수정 (#22)
* fix: interval 과정중 에러 방출시 무시하고 계속 interval 되도록 수정한다 * refactor: 로컬 로직이 실패하면 분산트랜잭션도 ack되지 않도록 수정한다 * test: TransactionHandlerAssertions을 사용하고 항상 초기화하도록 수정한다
- Loading branch information
Showing
30 changed files
with
503 additions
and
257 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
9 changes: 5 additions & 4 deletions
9
src/main/kotlin/org/rooftop/netx/api/TransactionCommitEvent.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,7 @@ | ||
package org.rooftop.netx.api | ||
|
||
data class TransactionCommitEvent( | ||
val transactionId: String, | ||
val nodeName: String, | ||
) | ||
class TransactionCommitEvent( | ||
transactionId: String, | ||
nodeName: String, | ||
group: String, | ||
): TransactionEvent(transactionId, nodeName, group) |
5 changes: 5 additions & 0 deletions
5
src/main/kotlin/org/rooftop/netx/api/TransactionCommitHandler.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
package org.rooftop.netx.api | ||
|
||
@Target(AnnotationTarget.FUNCTION) | ||
@Retention(AnnotationRetention.RUNTIME) | ||
annotation class TransactionCommitHandler |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package org.rooftop.netx.api | ||
|
||
abstract class TransactionEvent( | ||
val transactionId: String, | ||
val nodeName: String, | ||
val group: String, | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,7 @@ | ||
package org.rooftop.netx.api | ||
|
||
data class TransactionJoinEvent( | ||
val transactionId: String, | ||
val nodeName: String, | ||
) | ||
class TransactionJoinEvent( | ||
transactionId: String, | ||
nodeName: String, | ||
group: String, | ||
): TransactionEvent(transactionId, nodeName, group) |
5 changes: 5 additions & 0 deletions
5
src/main/kotlin/org/rooftop/netx/api/TransactionJoinHandler.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
package org.rooftop.netx.api | ||
|
||
@Target(AnnotationTarget.FUNCTION) | ||
@Retention(AnnotationRetention.RUNTIME) | ||
annotation class TransactionJoinHandler |
9 changes: 5 additions & 4 deletions
9
src/main/kotlin/org/rooftop/netx/api/TransactionRollbackEvent.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,9 @@ | ||
package org.rooftop.netx.api | ||
|
||
data class TransactionRollbackEvent( | ||
val transactionId: String, | ||
val nodeName: String, | ||
class TransactionRollbackEvent( | ||
transactionId: String, | ||
nodeName: String, | ||
group: String, | ||
val cause: String?, | ||
val undo: String, | ||
) | ||
): TransactionEvent(transactionId, nodeName, group) |
5 changes: 5 additions & 0 deletions
5
src/main/kotlin/org/rooftop/netx/api/TransactionRollbackHandler.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
package org.rooftop.netx.api | ||
|
||
@Target(AnnotationTarget.FUNCTION) | ||
@Retention(AnnotationRetention.RUNTIME) | ||
annotation class TransactionRollbackHandler |
9 changes: 5 additions & 4 deletions
9
src/main/kotlin/org/rooftop/netx/api/TransactionStartEvent.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,7 @@ | ||
package org.rooftop.netx.api | ||
|
||
data class TransactionStartEvent( | ||
val transactionId: String, | ||
val nodeName: String, | ||
) | ||
class TransactionStartEvent( | ||
transactionId: String, | ||
nodeName: String, | ||
group: String, | ||
) : TransactionEvent(transactionId, nodeName, group) |
5 changes: 5 additions & 0 deletions
5
src/main/kotlin/org/rooftop/netx/api/TransactionStartHandler.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
package org.rooftop.netx.api | ||
|
||
@Target(AnnotationTarget.FUNCTION) | ||
@Retention(AnnotationRetention.RUNTIME) | ||
annotation class TransactionStartHandler |
129 changes: 72 additions & 57 deletions
129
src/main/kotlin/org/rooftop/netx/engine/AbstractTransactionDispatcher.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,84 +1,99 @@ | ||
package org.rooftop.netx.engine | ||
|
||
import org.rooftop.netx.api.TransactionCommitEvent | ||
import org.rooftop.netx.api.TransactionJoinEvent | ||
import org.rooftop.netx.api.TransactionRollbackEvent | ||
import org.rooftop.netx.api.TransactionStartEvent | ||
import org.rooftop.netx.api.* | ||
import org.rooftop.netx.idl.Transaction | ||
import org.rooftop.netx.idl.TransactionState | ||
import org.springframework.context.ApplicationEventPublisher | ||
import reactor.core.publisher.Flux | ||
import reactor.core.publisher.Mono | ||
import reactor.core.scheduler.Schedulers | ||
import kotlin.reflect.KFunction | ||
|
||
abstract class AbstractTransactionDispatcher( | ||
private val eventPublisher: ApplicationEventPublisher, | ||
) { | ||
abstract class AbstractTransactionDispatcher { | ||
|
||
fun subscribeStream(transactionId: String): Flux<Pair<Transaction, String>> { | ||
return receive(transactionId) | ||
.flatMap { dispatchAndAck(it.first, it.second) } | ||
} | ||
protected val transactionHandlerFunctions = | ||
mutableMapOf<TransactionState, MutableList<Pair<KFunction<Mono<Any>>, Any>>>() | ||
|
||
protected abstract fun receive(transactionId: String): Flux<Pair<Transaction, String>> | ||
protected abstract fun initHandlers() | ||
|
||
fun dispatchAndAck(transaction: Transaction, messageId: String): Flux<Pair<Transaction, String>> { | ||
return Flux.just(transaction to messageId) | ||
.dispatch() | ||
.ack() | ||
fun dispatch(transaction: Transaction, messageId: String): Flux<Any> { | ||
return Mono.just(transaction.state) | ||
.filter { state -> transactionHandlerFunctions.containsKey(state) } | ||
.flatMapMany { state -> | ||
Flux.fromIterable( | ||
transactionHandlerFunctions[state] | ||
?: throw cannotFindMatchedHandlerFunctionException | ||
) | ||
} | ||
.flatMap { (function, instance) -> | ||
mapToTransactionEvent(transaction) | ||
.doOnNext { beforeInvokeHook(transaction, messageId) } | ||
.flatMap { function.call(instance, it) } | ||
} | ||
.doOnComplete { | ||
ack(transaction, messageId) | ||
.subscribeOn(Schedulers.boundedElastic()) | ||
.subscribe() | ||
} | ||
} | ||
|
||
private fun Flux<Pair<Transaction, String>>.dispatch(): Flux<Pair<Transaction, String>> { | ||
return this.flatMap { (transaction, messageId) -> | ||
when (transaction.state) { | ||
TransactionState.TRANSACTION_STATE_JOIN -> publishJoin(transaction) | ||
TransactionState.TRANSACTION_STATE_COMMIT -> publishCommit(transaction) | ||
TransactionState.TRANSACTION_STATE_ROLLBACK -> publishRollback(transaction) | ||
TransactionState.TRANSACTION_STATE_START -> publishStart(transaction) | ||
else -> error("Cannot find matched transaction state \"${transaction.state}\"") | ||
}.map { transaction to messageId } | ||
} | ||
} | ||
private fun mapToTransactionEvent(transaction: Transaction): Mono<TransactionEvent> { | ||
return when (transaction.state) { | ||
TransactionState.TRANSACTION_STATE_START -> Mono.just( | ||
TransactionStartEvent( | ||
transaction.id, | ||
transaction.serverId, | ||
transaction.group | ||
) | ||
) | ||
|
||
private fun publishJoin(it: Transaction): Mono<Transaction> { | ||
return Mono.just(it) | ||
.doOnNext { | ||
eventPublisher.publishEvent( | ||
TransactionJoinEvent( | ||
it.id, | ||
it.serverId | ||
) | ||
TransactionState.TRANSACTION_STATE_COMMIT -> Mono.just( | ||
TransactionCommitEvent( | ||
transaction.id, | ||
transaction.serverId, | ||
transaction.group, | ||
) | ||
} | ||
} | ||
) | ||
|
||
private fun publishCommit(it: Transaction): Mono<Transaction> { | ||
return Mono.just(it) | ||
.doOnNext { eventPublisher.publishEvent(TransactionCommitEvent(it.id, it.serverId)) } | ||
} | ||
TransactionState.TRANSACTION_STATE_JOIN -> Mono.just( | ||
TransactionJoinEvent( | ||
transaction.id, | ||
transaction.serverId, | ||
transaction.group, | ||
) | ||
) | ||
|
||
private fun publishRollback(transaction: Transaction): Mono<Transaction> { | ||
return findOwnTransaction(transaction) | ||
.doOnNext { | ||
eventPublisher.publishEvent( | ||
TransactionState.TRANSACTION_STATE_ROLLBACK -> findOwnTransaction(transaction) | ||
.map { | ||
TransactionRollbackEvent( | ||
transaction.id, | ||
transaction.serverId, | ||
transaction.group, | ||
transaction.cause, | ||
it.undo | ||
transaction.undo, | ||
) | ||
) | ||
} | ||
.map { transaction } | ||
} | ||
|
||
else -> throw cannotFindMatchedTransactionEventException | ||
} | ||
} | ||
|
||
protected abstract fun findOwnTransaction(transaction: Transaction): Mono<Transaction> | ||
|
||
private fun publishStart(it: Transaction): Mono<Transaction> { | ||
return Mono.just(it) | ||
.doOnNext { | ||
eventPublisher.publishEvent(TransactionStartEvent(it.id, it.serverId)) | ||
} | ||
} | ||
protected abstract fun ack( | ||
transaction: Transaction, | ||
messageId: String | ||
): Mono<Pair<Transaction, String>> | ||
|
||
protected abstract fun beforeInvokeHook( | ||
transaction: Transaction, | ||
messageId: String | ||
) | ||
|
||
protected abstract fun Flux<Pair<Transaction, String>>.ack(): Flux<Pair<Transaction, String>> | ||
private companion object { | ||
private val cannotFindMatchedTransactionEventException = | ||
java.lang.IllegalStateException("Cannot find matched transaction event") | ||
|
||
private val cannotFindMatchedHandlerFunctionException = | ||
IllegalStateException("Cannot find matched handler function") | ||
} | ||
} |
19 changes: 19 additions & 0 deletions
19
src/main/kotlin/org/rooftop/netx/engine/AbstractTransactionListener.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
package org.rooftop.netx.engine | ||
|
||
import org.rooftop.netx.idl.Transaction | ||
import reactor.core.publisher.Flux | ||
|
||
abstract class AbstractTransactionListener( | ||
private val transactionDispatcher: AbstractTransactionDispatcher, | ||
) { | ||
|
||
fun subscribeStream(transactionId: String): Flux<Pair<Transaction, String>> { | ||
return receive(transactionId) | ||
.flatMap { (transaction, messageId) -> | ||
transactionDispatcher.dispatch(transaction, messageId) | ||
.map { transaction to messageId } | ||
} | ||
} | ||
|
||
protected abstract fun receive(transactionId: String): Flux<Pair<Transaction, String>> | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 1 addition & 1 deletion
2
...utoconfig/EnableDistributedTransaction.kt → ...netx/meta/EnableDistributedTransaction.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package org.rooftop.netx.meta | ||
|
||
import org.springframework.stereotype.Component | ||
|
||
@Component | ||
@Target(AnnotationTarget.CLASS) | ||
@Retention(AnnotationRetention.RUNTIME) | ||
annotation class TransactionHandler |
Oops, something went wrong.