So I want to create a simple food order service, but this service require some information from the other service so I use saga pattern. Here's how it should work if I order a food, first it will attempt to create order but if there's any error it will retry for 3 times and publish either success or failed event.
Here's the sample code.
@Saga
class OrderCreationSaga {
@Transient
@Autowired
private lateinit var commandGateway: CommandGateway
@Transient
@Autowired
private lateinit var eventScheduler: EventScheduler
@Transient
@Autowired
private lateinit var eventBus: EventBus
@Transient
@Autowired
private lateinit var scheduleToken: ScheduleToken
private lateinit var orderId: String
private var retryCounter = 1
@StartSaga
@SagaEventHandler(associationProperty = "orderId")
fun on(event: OrderCreationAttempted) {
this.orderId = event.orderId
eventBus.publish(GenericEventMessage(event.toOrderCreationRequested()))
}
@SagaEventHandler(associationProperty = "orderId")
fun on(event: OrderCreationRequested) {
try {
// send data to another service
orderCreationService.createOrder(event).block()
eventBus.publish(GenericEventMessage(
OrderCreationSuccess(
orderId = event.orderId
))
)
} catch (error: Throwable) {
// catching request error, retry for 3 times
if (this.retryCounter == 3) {
eventBus.publish(GenericEventMessage(
OrderCreationFailed(
orderId = this.orderId,
)
))
} else {
eventBus.publish(GenericEventMessage(
OrderCreationRetry(
orderId = event.orderId,
)
))
this.retryCounter++
}
}
}
@EndSaga
@SagaEventHandler(associationProperty = "orderId")
fun on(event: OrderCreationSuccess) {
// do the success job
}
@EndSaga
@SagaEventHandler(associationProperty = "orderId")
fun on(event: OrderCreationFailed) {
// do the failed job
}
@SagaEventHandler(associationProperty = "orderId")
fun on(event: OrderCreationRetry) {
val duration = Duration.ofSeconds(30)
val scheduleEvent = OrderCreationRequested(orderId = event.orderId)
scheduleToken = eventScheduler.schedule(duration, scheduleEvent)
}
}
But the weird thing happens so after it published a success event it will publish a OrderCreationRequested event again for some reason (I know this because I've checked the event log inside axonserver). This keeps looping infinitely, is this because my code or some configuration or could be something else?
So the problem was I forgot to set my username and password for my MongoDB and then someone just trying to delete all of my data including tracking token for axon-server. So because of the tracking token has been delete axon-server start creating the new one with 0 value which makes all the event start rerunning again and again. I solve this problem by just add the username and password for my MongoDB.