我的应用程序有一个长时间运行的任务(任何时间从5分钟到2小时),我可以通过管理面板开始。
我需要一个很好的方法来了解任务当前是否正在运行,因此我可以在管理面板上显示状态并防止任务被启动两次。
目前我的代码看起来像这样(简化):
object TaskMonitor extends Controller {
var isRunning = false
// Displays the task status on the admin panel
def status = Action {
Ok.chunked(running &> Comet(callback = "parent.running"))
}
// Check task status every 100 ms
lazy val running: Enumerator[String] = {
Enumerator.generateM {
Promise.timeout(Some(isRunning.toString), 100 milliseconds)
}
}
// start the task, but only if it's not already running
def startTask = Action {
if (!isRunning) {
isRunning = true
val f = scala.concurrent.Future { Task.start }
f onComplete {
case _ => isRunning = false
}
}
Ok
}
}
显然这有各种各样的问题,主要是因为我的控制器中有不同步的可变状态(isRunning变量)。
什么是正确的方法来实现我想要实现的目标?
答案 0 :(得分:1)
你是对的,你有不同步的可变状态。这真的是个问题吗?我的意思是这是你的管理员吗?你要发送多少并发“startTask”?
在Play中处理此问题的推荐方法!是使用Akka演员 - 你不需要任何额外的依赖,玩!包括Akka已经。
创建一个演员来保存您的isRunning
值;在startTask
中,您可以向actor发送消息以启动任务(actor将检查该任务是否尚未运行)。要发送任务的当前状态,您可以向actor查询值isRunning
。
这将为您提供受保护的可变状态。您可以选择确定它是否真的值得一试。