Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala 为什么我的Akka FSM活动超时?_Scala_Timeout_Akka_State Machine_Fsm - Fatal编程技术网

Scala 为什么我的Akka FSM活动超时?

Scala 为什么我的Akka FSM活动超时?,scala,timeout,akka,state-machine,fsm,Scala,Timeout,Akka,State Machine,Fsm,作为Akka FSM的学习练习,我在一家咖啡店模拟了一个简化的订单处理流程。附件是状态转换图。然而,我写的一个测试用例超时了,我不明白为什么 FSM(为简洁起见,未显示案例类别): 测试失败: it should "stay in OrderPlaced state as long as customer has not paid" in { val orderSystem = system.actorOf(Props[OrderSystem]) orderSystem ! Ba

作为Akka FSM的学习练习,我在一家咖啡店模拟了一个简化的订单处理流程。附件是状态转换图。然而,我写的一个测试用例超时了,我不明白为什么

FSM(为简洁起见,未显示案例类别):

测试失败:

it should "stay in OrderPlaced state as long as customer has not paid" in {
    val orderSystem = system.actorOf(Props[OrderSystem])
    orderSystem ! BaristaIsAvailable(OrderPending, PaymentPending)

    orderSystem ! SubscribeTransitionCallBack(testActor)

    expectMsg(CurrentState(orderSystem, OrderPlaced))

    orderSystem ! BaristaIsAvailable(OrderPlaced, PaymentPending)

    expectMsg(CurrentState(orderSystem, OrderPlaced))
}
日志:


SubscribeTransitionCallBack
将只传递一次
当前状态
,然后只传递
转换
回调

您可以尝试这样做:

it should "stay in OrderPlaced state as long as customer has not paid" in {

  val orderSystem = TestFSMRef(new OrderSystem)

  orderSystem ! SubscribeTransitionCallBack(testActor)
  // fsm first answers with current state
  expectMsgPF(1.second. s"OrderPending as current state for $orderSystem") { 
    case CurrentState('orderSystem', OrderPending) => ok 
  }

  // from now on the subscription will yield 'Transition' messages
  orderSystem ! BaristaIsAvailable(OrderPending, PaymentPending)
  expectMsgPF(1.second, s"Transition from OrderPending to OrderPlaced for $orderSystem") { 
    case Transition(`orderSystem`, OrderPending, OrderPlaced) => ok 
  }

  orderSystem ! BaristaIsAvailable(OrderPlaced, PaymentPending)
  // there is no transition, so there should not be a callback.
  expectNoMsg(1.second)

/*
  // alternatively, if your state data changes, using TestFSMRef, you could check state data blocking for some time
  awaitCond(
    p = orderSystem.stateData == ???, 
    max = 2.seconds, 
    interval = 200.millis,
    message = "waiting for expected state data..."
  )
  // awaitCond will throw an exception if the condition is not met within max timeout
*/
  success
}

您并没有从FSM发回任何回复,您的expectMsg失败是正常的,因为在测试中会看到一个探针。这对我的案子有用吗<代码>val probe=TestProbe();expectMsg@AbhijitSarkar在测试用例中使用
TestProbe
肯定是一种可行的方法。但是它使事情变得更加复杂,而不是改善任何事情。最后一个问题。在上面的日志中,我看到当我发送第二个事件时,它不仅改变了状态,而且匹配了案例4(在日志中打印为4)。这是预期的行为,如果我对不匹配的事件使用
goto
,它将进入该状态,但不匹配任何
case
语句。如果将
goto
用于与匹配的事件,则它将进入新状态,并与
案例
匹配?@AbhijitSarkar我不理解这个问题。但是我要说的是,对于第二条消息,我们完全希望事件与
when(OrderPlaced)
state函数中的案例4匹配。由于第一个案例与错误的
数据不匹配,案例2和3与消息本身不匹配,案例4与任何消息匹配,而
stateData与数据(uu,PaymentPending)
,这是您在
when(OrderPending)
状态函数的第一条消息后设置的。顺便说一句,案例4以不改变状态的
stay()
结束。
2015-09-22 23:29:15.236 [order-system-akka.actor.default-dispatcher-2] [DEBUG] n.a.s.o.OrderSystem - processing Event(BaristaIsAvailable(OrderPending,PaymentPending),Data(OrderPending,PaymentPending)) from Actor[akka://order-system/system/testActor1#-2143558060]
2015-09-22 23:29:15.238 [order-system-akka.actor.default-dispatcher-2] [INFO ] n.a.s.o.OrderSystem - Entering state: OrderPlaced with payment activity: PaymentPending from state: OrderPending with payment activity: PaymentPending.
2015-09-22 23:29:15.239 [order-system-akka.actor.default-dispatcher-2] [DEBUG] n.a.s.o.OrderSystem - transition OrderPending -> OrderPlaced
4
2015-09-22 23:29:15.242 [order-system-akka.actor.default-dispatcher-2] [DEBUG] n.a.s.o.OrderSystem - processing Event(BaristaIsAvailable(OrderPlaced,PaymentPending),Data(OrderPending,PaymentPending)) from Actor[akka://order-system/system/testActor1#-2143558060]
[31m- should stay in OrderPlaced state as long as customer has not paid *** FAILED ***[0m
[31m  java.lang.AssertionError: assertion failed: timeout (3 seconds)
it should "stay in OrderPlaced state as long as customer has not paid" in {

  val orderSystem = TestFSMRef(new OrderSystem)

  orderSystem ! SubscribeTransitionCallBack(testActor)
  // fsm first answers with current state
  expectMsgPF(1.second. s"OrderPending as current state for $orderSystem") { 
    case CurrentState('orderSystem', OrderPending) => ok 
  }

  // from now on the subscription will yield 'Transition' messages
  orderSystem ! BaristaIsAvailable(OrderPending, PaymentPending)
  expectMsgPF(1.second, s"Transition from OrderPending to OrderPlaced for $orderSystem") { 
    case Transition(`orderSystem`, OrderPending, OrderPlaced) => ok 
  }

  orderSystem ! BaristaIsAvailable(OrderPlaced, PaymentPending)
  // there is no transition, so there should not be a callback.
  expectNoMsg(1.second)

/*
  // alternatively, if your state data changes, using TestFSMRef, you could check state data blocking for some time
  awaitCond(
    p = orderSystem.stateData == ???, 
    max = 2.seconds, 
    interval = 200.millis,
    message = "waiting for expected state data..."
  )
  // awaitCond will throw an exception if the condition is not met within max timeout
*/
  success
}