Scala 使用自定义邮箱和具有至少EastOnceDelivery的持久参与者
问题Scala 使用自定义邮箱和具有至少EastOnceDelivery的持久参与者,scala,akka,akka-persistence,Scala,Akka,Akka Persistence,问题 如何在持久化服务器的receiveCommand中获取和记录消息 是否在自定义邮箱中具有AtLeastOnceDelivery的参与者? 如何在自定义邮箱排队和出列中获取持久参与者的名称 我有一个自定义邮箱,其中包含以下MessageQueue: 问题在于,持久参与者在receiveCommand中接收到的消息根本不会记录在出列或入列中。只记录持久化。 此外,下面我的代码中的owner.get.path.name永远不会获得持久参与者的名称。它的名称类似于recoveryPermitte
receiveCommand
中获取和记录消息
是否在自定义邮箱中具有AtLeastOnceDelivery
的参与者?
MessageQueue:
问题在于,持久参与者在receiveCommand
中接收到的消息根本不会记录在出列或入列中。只记录持久化。
此外,下面我的代码中的owner.get.path.name
永远不会获得持久参与者的名称。它的名称类似于recoveryPermitter
和inmemory快照存储
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
的持久参与者,下面是receiveCommand
和updateState
方法:我在上面的自定义邮箱中的排队和退队记录如下:
排队
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])
这表明邮箱在收到myChildClient
中的BuyGoods
命令消息后,正在处理持久化Goods
事件。它只记录商品的持久性
,而不记录购买商品的排队或退队(偷看)
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
}
def updateState(evt:evt):单位=evt匹配{
如果state.CashBal-金额<0,则案例还原平衡(deliveryId,金额)⇒
确认交付(交付ID)
抛出不足余额(s“客户端无法从${state.CashBal}提取$amount”)
案例e:还原平衡⇒ state=ClientState(state.CashBal-e.amount)
确认交付(例如交付ID)
deliver(paymentsActor)(deliveryId=>PaymentMessage(deliveryId,e.amount))
案例e:货物=>
交付(stockActor)(交付ID=>ReduceStock(交付ID,e.name,e.amount))
案例e:AddCredit=>
state=ClientState(state.CashBal+e.amount)
案例e:PaymentAccepted=>
日志信息(“客户确认付款:+e)
确认交付(例如交付ID)
}
覆盖def接收命令:接收={
//向stockActor索取货物
案例c:购买商品=>
log.info(“收到的客户:+c”)
persistAsync(货物(c.名称,c.金额))(更新)
//付款参与者确认付款
}
在此处查看答案:在此处查看答案: