使用AtLeastOnceDelivery处理自定义邮箱和永久参与者

时间:2019-03-15 02:42:26

标签: scala akka akka-persistence

问题

  1. 如何在持久性的receiveCommand中获取和记录消息 演员与自定义邮箱中的AtLeastOnceDelivery入队和出队?
    1. 如何在自定义邮箱入队和出队中获取持久角色的名称?

我有一个自定义邮箱,其中包含以下MessageQueue:

问题在于,持久性参与者在receiveCommand中接收到的消息根本不在出队或入队中记录。只记录持久性。 另外,我下面的代码中的owner.get.path.name永远不会获得持久角色的名称。它会获得recoveryPermitterinmemory-snapshot-store之类的名称。

class CustomMailbox(val backend: MessageQueue, owner: Option[ActorRef], system: Option[ActorSystem]) extends MessageQueue {

    override def enqueue(receiver: ActorRef, handle: Envelope): Unit = {
        // Simulate DROP
        println(s"messageType in  ${owner.get.path.name}"+handle.message.getClass.toString)
        val canEnqueue = Math.random() > 0.95
        println(s"enqueing for ${owner.get.path}: $handle")
        backend.enqueue(receiver, handle)
    }

    override def dequeue(): Envelope = {
        val mb:UnboundedMailbox.MessageQueue = backend.asInstanceOf[UnboundedMailbox.MessageQueue]
        val peek = mb.queue.peek()
        println(s"peeking for ${owner.get.path.name}: $peek")
        if(peek != null) {
            println(s"messageType in degueue ${owner.get.path.name}"+peek.message.getClass.toString)
            val canDequeue = Math.random() > 0.9
                println(s"dequeing for ${owner.get.path}: $peek")
                backend.dequeue()
        }

        else
        {
            null
        }
    }

    override def numberOfMessages: Int = backend.numberOfMessages

    override def cleanUp(owner: ActorRef, deadLetters: MessageQueue): Unit = backend.cleanUp(owner, deadLetters)

    override def hasMessages: Boolean = backend.hasMessages
}

例如,我有一个名称为childclient的持久性参与者,下面是receiveCommandupdateState方法:我在自定义邮箱中的入队和出队将记录如下内容:< / p>

入队

 enqueing for akka://WebShop/system/inmemory-journal: Envelope(WriteMessages(Vector(AtomicWrite(List(PersistentImpl(Goods(goods,5),1,my-Client-id,,false,Actor[akka://WebShop/user/webShopActor#-659139690],be7c37ad-9c0e-4d77-84ec-d9fd94b5f623)))),Actor[akka://WebShop/user/webShopActor/clientChild#-1139440822],2),Actor[akka://WebShop/user/webShopActor/clientChild#-1139440822])

出队/偷窥

peeking for inmemory-journal: 
Envelope(WriteMessages(Vector(AtomicWrite(List(PersistentImpl(Goods(goods,5),1,my-Client-id,,false,Actor[akka://WebShop/user/webShopActor#-659139690],be7c37ad-9c0e-4d77-84ec-d9fd94b5f623)))),Actor[akka://WebShop/user/webShopActor/clientChild#-1139440822],2),Actor[akka://WebShop/user/webShopActor/clientChild#-1139440822])

这表明邮箱在我的Goods中收到BuyGoods命令消息后,正在处理持久化ChildClient事件。它仅记录Goods的持久性,但不记录BuyGoods的入队或出队(偷看)。

 def updateState(evt: Evt): Unit = evt match {
    case ReduceBalance(deliveryId, amount) if state.CashBal - amount < 0 ⇒
      confirmDelivery(deliveryId)
      throw InsufficientBalance(s"Client cannot withdraw $amount from ${state.CashBal}")
    case e: ReduceBalance ⇒ state = ClientState(state.CashBal - e.amount)
      confirmDelivery(e.deliveryId)
      deliver(paymentsActor)(deliveryId => PaymentMessage(deliveryId, e.amount))
    case e: Goods =>
      deliver(stockActor)(deliveryId => ReduceStock(deliveryId, e.name, e.amount))
    case e: AddCredit =>
      state = ClientState(state.CashBal + e.amount)
    case e: PaymentAccepted =>
      log.info("client confirmed payment:" + e)
      confirmDelivery(e.deliveryId)
  }


  override def receiveCommand: Receive = {
    //request for goods from stockActor

    case c: BuyGoods =>
      log.info("Client Recieved: " + c)
      persistAsync(Goods(c.name, c.Amount))(updateState)
    //payments actor confirms payment

  }

0 个答案:

没有答案