zoukankan      html  css  js  c++  java
  • actor binary tree lab4

    forward 与 ! (tell) 的差异,举个例子:

    Main(当前actor): topNode ! Insert(requester, id=1, ele = 2)

    topNode: root ! Insert(requester, id=1, ele = 2)

    对于root而言,Insert消息的来源是topNode

    假如第二行替换为

    topNode: root forward Insert(requester, id=1, ele = 2)

    此时,对于root而言,Insert消息的来源是Main

    从上面的例子可以看出,! 和 forward之间是有差别的,但是差别本身比较tricky,会增加理解的成本,所以传递消息时,把消息的actorRef作为参数传递会简单很多。

    在lab4中,就需要考虑到!与forward的异同点

    testcase 的 code

      test("proper inserts and lookups") {
        val topNode = system.actorOf(Props[BinaryTreeSet])
    
        topNode ! Contains(testActor, id = 1, 1)
        expectMsg(ContainsResult(1, false))
    
        topNode ! Insert(testActor, id = 2, 1)
        topNode ! Contains(testActor, id = 3, 1)
    
        expectMsg(OperationFinished(2))
        expectMsg(ContainsResult(3, true))
      }

    结合topNode,与root的处理逻辑

      val normal: Receive = {
    //    这个forward非常重要,不能写成 !,不然第一个testcase都不过去
        case operation: Operation => root ! operation
        case GC => {
          //garbageCollecting需要先变,因为节点的复制可能会很久
          val newRoot = createRoot
          context.become(garbageCollecting(newRoot))
          root ! CopyTo(newRoot) 
          
        }
        case _ => println("unknown operation")
      }
        
    // root 的处理逻辑
      case Insert(requester, id, elem) => if(this.elem == elem) { if(this.removed) this.removed = false requester ! OperationFinished(id) } else { val child = if(this.elem > elem) Left else Right if(subtrees contains child) subtrees(child) ! Insert(requester, id, elem) else { subtrees += child -> context.actorOf(props(elem, false)) requester ! OperationFinished(id) } }

    在source code中,topNode收到消息后,把消息传递给root,root认为消息的来源是topNode。假如消息不绑定requester参数,那么通过sender获得actor是tiopNode,而不是main。我们在testcase中做assertion的话,肯定就是错的。

    另外,上例中用到了testActor,它是implicit变量,用于处理发送到main中的消息。主要是测试方便。

    一个debug了5个小时的bug

    case msg: Operation =>
            pendingQueue = pendingQueue.enqueue(msg)

    pendingQueue.enqueue(msg) 并不能更新pendingQueue自己,必须重新赋值才行。

  • 相关阅读:
    Code Review 五问五答
    JavaScript 10分钟入门
    swagger editor使用
    Tyk API网关介绍及安装说明
    Castle 多继承选择
    线程信息的获取和设置
    s3 api接口的调用
    在Hadoop集群上的HBase配置
    OpenStack 单元测试
    在Hadoop集群上的Hive配置
  • 原文地址:https://www.cnblogs.com/xinsheng/p/4322597.html
Copyright © 2011-2022 走看看