嗨我使用scala(2.8.1)来实现一个使用actor的耗时任务处理程序,但是,我无法在运行单元测试时清理它,所以我的单元测试永远挂起.
我怎么称呼方法是:
val configs = new ProjectsConfig("XXXXXXXXXXXXX")
try {
configs.start
configs.init//time consuming stuff
} finally {
configs.destory
configs.stop
}
Run Code Online (Sandbox Code Playgroud)
我打算做的是保持actor的引用并在每个on上调用exit,代码片段如下:
但是,似乎效果不佳.在这种情况下如何清理所有演员?
class ProjectsConfig(val url: String) extends Actor {
private var actors: List[Actor] = List()
private object Stop
def init = {
val caller = this;
for (projectConfig <- list) {
val myActor: Actor = actor {
caller ! projectConfig.instantiate
}
actors = actors ::: List(myActor)
}
}
def act() {
while (true) {
receive {
case project: Project =>
Projects.update(project)
case Stop => exit()
}
}
}
def destory {
for (actor <- actors) {
try {
actor ! exit
} catch {
case e => System.out.println(e.printStackTrace)
}
}
}
def stop() {
this ! Stop
}
Run Code Online (Sandbox Code Playgroud)
1)根据你的具体情况,我会简化
val myActor: Actor = actor {
caller ! projectConfig.instantiate
}
Run Code Online (Sandbox Code Playgroud)
就只是caller ! projectConfig.instantiate. 您已经从参与者的子系统进行了调用,因此不需要额外的包装。
除此之外,虽然通常建议从 actor 的环境中调用 actor(生成调用),但这根本不是“必须”的(如果您直接在非 actor 环境中调用 actor,也不会发生任何邪恶情况)。就您而言,包装调用反而会增加问题(样板文件和不一致)。
2)实际发生的情况actor ! exit是actor ! Actor.exit(假设您有通配符导入Actor)。此代码在尝试计算 时会引发异常Actor.exit,并且不会向参与者发送任何内容。为了停止 actor,您必须调用exit它的实例。它可以通过消息发送来完成,这将调用 protected exit:
actor{
loop{
react{
case `exit => exit('stop)
}
}
}
Run Code Online (Sandbox Code Playgroud)