Skip to content

Latest commit

 

History

History
42 lines (32 loc) · 1.72 KB

README.md

File metadata and controls

42 lines (32 loc) · 1.72 KB

"Buying item" saga example

Sequence diagram of the transaction

sequence diagram

Diagram of the saga's states

FSM

Implementation of the saga

type Step[A, B] = PersistedSaga[F, A, B, HNil, OrderId, Json]

val createOrder: Step[BuyItem, DeferredOrder] = PersistedSaga(
  (args: BuyItem)  orderService.createOrder(args.item).map(DeferredOrder(_, args.item)),
  (order: DeferredOrder, cause: Throwable)  orderService.markAsFailed(order.orderId, cause)
)(_.orderId)

val reserveCredit: Step[DeferredOrder, CreditReserved] = PersistedSaga(
  (order: DeferredOrder) 
    billingService.reserveCredit(order.item.price).map(CreditReserved(order.orderId, _, order.item)),
  (credit: CreditReserved, _: Throwable)  billingService.returnCredit(credit.id)
)(_.orderId)

val findItem: Step[CreditReserved, ItemFound] = PersistedSaga(
  (credit: CreditReserved)  storeService.findItem(credit.item).map(ItemFound(credit.orderId, _, credit.item)),
  (item: ItemFound, _: Throwable)  storeService.revertItem(item.code)
)(_.orderId)

val orderDelivery: Step[ItemFound, DeliveryOrdered] = PersistedSaga(
  (item: ItemFound)  deliveryService.orderDelivery(item.item).map(DeliveryOrdered(item.orderId, _)),
  (deliveryOrder: DeliveryOrdered, _: Throwable)  deliveryService.cancelOrder(deliveryOrder.deliveryId)
)(_.orderId)

val completeOrder = Saga(
  (deliveryOrdered: DeliveryOrdered) 
    orderService.markAsCompleted(deliveryOrdered.orderId).as(Done(deliveryOrdered.orderId))
)

createOrder andThen reserveCredit andThen findItem andThen orderDelivery completeOn completeOrder

More details here: BuyingItemSaga.scala