Scala Actor 学习2

1. Akka Actor中的方法

preStart

在Actor启动之后立即调用,在重启过程中默认调用postRestart

postStop

在一个Actor停止之后,它可以执行任何的清扫工作(clean up)。在Akka documentation中,必须保证在消息队列对于这个Actor禁用之后才能执行

preRestart

当一个新的Actor重启,进程会通知老的Actor(之前执行异常任务重启)和触发异常的消息

postRestart

当有新的异常导致重启时,会调用postRestart方法


2.启动一个Actor

如果你想启动一个actor,或者是想控制actor的启动

Akka actor 是异步启动的,当通过actorOf的方法生成一个actor并启动时。

你可以使用context.actorOf方法创造一个child actor

假设有一个actor,它的一个功能过于复杂,为了降低复杂度,可以将这个功能划分成多个更小粒度的,更易管理的子任务,启动新的child actors,

例子:

import akka.actor._
class HelloActor extends Actor{
  def receive = {
    ....
  }
}
object LifecycleDemo{
  def main(args: Array[String]): Unit = {
    val system = ActorSystem("HelloSystem")
    //创造一个actor并启动
    val helloActor = system.actorOf(Props[HelloActor],name = "helloactor")
    helloActor ! "hello"
  }
}

父类子类

class Child extends Actor{
  def receive ={
    .....
  }
}

class Parent extends Actor{
  val child = context.actorOf(Props[Child],name = "Child")
  def receive={
    ......
  }
}

3.Actor Path

可以把Actor Path是通过字符串对Actor层级关系进行组合用以标识唯一Actor的一种方式。在创建Actor Path时,不用创建Actor,但如果没有创建对应的Actor,则不能创建Actor Reference。还可以创建一个Actor,再终止它,然后再以相同的Actor Path再创建一个新的Actor。新创建的Actor是Actor的新化身(Incarnation),但与旧的Actor并不是同一个。对于这个新化身而言,持有旧Actor的Actor Reference并不是有效的。消息发送给旧的Actor Reference,但不会被传递给新化身,即使它们具有相同的路径。

有两种方式可以获得Actor Reference:创建Actor或查找。

要创建Actor,可以调用ActorSystem.actorOf(),它创建的Actor在guardian actor之下;接着可以调用ActorContext.actorOf()在刚才创建的Actor内生成Actor树。这些方法会返回新创建的Actor的引用。每个Actor都可以直接访问Actor Context来或得它自身、Parent以及所有Children的引用。

要查找Actor Reference,则可调用ActorSystem.actorSelection()方法。要获得限定到特定Actor的生命周期中的ActorRef,可以使用sender引用来发送一条消息如内建的Identity消息给Actor。

//本地path
"akka://my-sys/user/service-a/worker1"   
//远程path
"akka.tcp://my-sys@host.example.com:5678/user/service-b"
//akka集群
"cluster://my-cluster/service-c"


4.Stopping Actors

这里有几种方法去停止Akka actors s

常用的方法:System.stop(actorRef)     /     context.stop(actorRef)

还有其他两种方法:  Send the actor a PosionPill message

                                       Program a  gracefulStop

1. actorSystem.stop(actorRef)  在ActorSystem level 停止actor

2. 隐式的被认定为在一个actor内使用,可以用context.stop(childActor)方式停止child actor

3. Actor可以停止本身  context.stop(self)

4.通过发送PosionPill message 来stop actor


区别:

Stop 方法:actor会继续处理当前的消息(如果有),但是不会处理additional message

PosionPill message : 对已经传进来的消息(mailbox)全部进行处理,处理完毕之后在停止


在 official Akka actor documentation 中描述 actorSystem.stop()和context.stop()

1. actor的终止是异步的,stop方法可能在actor停止之前就返回了

2.actor会继续处理的当前消息,但不会再处理附加的消息

3.actor 停止分为两步:a.挂起(suspends)mailbox,向该actor的所有child发送stop消息

                                          b.当所有的child终止,当有actor不回应(block)会等待

4 .当没有额外的消息被处理,它们被发送到ActorSystem的deadLetters actor中


gracefulStop 方法

正如名字所描述的,如果你想等待一段再时间停止。

例子:package actortests.gracefulstop
import akka.actor._
import akka.pattern.gracefulStop
import scala.concurrent.{Await, ExecutionContext, Future}
import scala.concurrent.duration._
import scala.language.postfixOps
class TestActor extends Actor {
def receive = {
case _ => println("TestActor got message")
   }
override def postStop { println("TestActor: postStop") }
   }
object GracefulStopTest extends App {
val system = ActorSystem("GracefulStopTest")
val testActor = system.actorOf(Props[TestActor], name = "TestActor")
// try to stop the actor gracefully
try {
val stopped: Future[Boolean] = gracefulStop(testActor, 2 seconds)(system)
Await.result(stopped, 3 seconds)
println("testActor was stopped")
  } catch {
case e:Exception => e.printStackTrace
  } finally {
system.shutdown
  }

}

在Scaladoc中,gracefulStop(actorRef , timeout),返回一个Future[actor中存在的消息被成功处理,然后actor被终止],如果actor没有在时间内终止,Future返回一个ActorTimeoutException。为了让这个例子更加简单,使用了Await.result,会加长等待时间
























  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值