我有一个Play
插件,执行每15分钟这样的方法:如何确保只有一个播放实例实际运行在一个特定时刻的方法
import scala.concurrent.Future
import scala.concurrent.duration._
import play.api.libs.concurrent.Akka
import play.api.libs.concurrent.Execution.Implicits.defaultContext
import play.api.{Application, Plugin}
import akka.actor.Cancellable
class AuthPlugin(app: Application) extends Plugin {
private var cancellableDoSomething: Option[Cancellable] = None
...
override def onStart = {
cancellableDoSomething = Some(
Akka.system.scheduler.scheduleOnce(0.seconds) {
doSomething.foreach { _ =>
Akka.system.scheduler.scheduleOnce(15.minutes)(doSomething)
}
}
)
}
override def onStop = {
cancellableDoSomething.foreach(_.cancel)
}
}
object AuthPlugin {
...
def doSomething: Future[Unit] = {
// Access to shared DB here...
}
}
让我们假设我有我的Play
两个实例应用程序运行在两台不同的主机上,每台主机每15分钟调用一次doSomething
。
如何确保只有一个实例在某个特定时刻实际运行doSomething
?
编辑
两个Play
实例访问同一个数据库,并doSomething
进程状态pending
记录。在处理完状态为pending
的记录后,它会更新为状态processed
。
如果第一Play
实例查询数据库挂单并在处理他们的第二Play
实例中运行相同的查询时,其获得的是还包括挂起已经由第一Play
例如查询订单,但尚未处理的记录集。为避免这种情况,当且仅当没有其他正在执行它的实例时,实例才能调用doSomething
。
我可以实现了一种基于DB-信号的地方获取第一Play
例如,它字段的值设置为1
或任何其他...但因为如果Play
实例失败这种解决方案并不稳定,从来没有将字段设置为0
,然后其他Play
实例不再能够获取信号量并调用doSomething
。
我假设你有一个共享资源问题。你能描述你想要达到的目标吗? – Aaron
由于每个游戏应用都运行在不同主机上的独立JVM上,因此您有两种选择:使用某些外部服务进行同步或自行实现此类同步,例如在Akka – maks
的帮助下创建nfs数据库机器共享创建文件并使用男人2在它上面 – ayvango