• 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自己,必须重新赋值才行。

  • 相关阅读:
    [IOS/翻译]Core Services Layer
    JEval使用实例
    Spring面试总结
    对easyui datagrid进行扩展,当滚动条拉直最下面就异步加载数据。
    虚拟机无法安装64位系统,是否说明硬件不支持?
    zh-cn,zh-tw,en-us,en-gb等网页语言代码一览表
    Python 计算程序运行时间
    美国教授是如何评价中国研究生的
    过来人谈在美国大学里的中国研究生
    javascript 十六进制与RGB颜色值的相互转换
  • 原文地址:https://www.cnblogs.com/xinsheng/p/4322597.html
Copyright © 2020-2023  润新知