instanciate async DBs at most one per second
this looks a bit dangerous thopull/9807/head
parent
6c37e20278
commit
8a4d577e74
|
@ -14,17 +14,22 @@ final class AsyncDb(
|
|||
driver: AsyncDriver
|
||||
)(implicit ec: scala.concurrent.ExecutionContext) {
|
||||
|
||||
private lazy val connection =
|
||||
private lazy val connection: Fu[(MongoConnection, Option[String])] =
|
||||
MongoConnection.fromString(uri) flatMap { parsedUri =>
|
||||
driver.connect(parsedUri, name.some).dmap(_ -> parsedUri.db)
|
||||
}
|
||||
|
||||
private def db: Future[DB] =
|
||||
private def makeDb: Future[DB] =
|
||||
connection flatMap { case (conn, dbName) =>
|
||||
conn database dbName.getOrElse("lichess")
|
||||
}
|
||||
|
||||
def apply(name: CollName) = new AsyncColl(name, () => db.dmap(_(name.value)))
|
||||
private val dbCache = new SingleFutureCache[DB](
|
||||
compute = () => makeDb,
|
||||
expireAfterMillis = 1000
|
||||
)
|
||||
|
||||
def apply(name: CollName) = new AsyncColl(name, () => dbCache.get.dmap(_.collection(name.value)))
|
||||
}
|
||||
|
||||
final class Db(
|
||||
|
@ -48,5 +53,5 @@ final class Db(
|
|||
logger.info(s"MongoDB connected to $uri in ${lap.showDuration}")
|
||||
}
|
||||
|
||||
def apply(name: CollName): Coll = db(name.value)
|
||||
def apply(name: CollName): Coll = db.collection(name.value)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
package lila.db
|
||||
|
||||
/* Will try to compute the future only once every `expireAfterMillis`,
|
||||
* and serve the current future to further `get` calls.
|
||||
* Not thread safe: it can compute the future more than once every `expireAfterMillis`.
|
||||
* It's a deliberate design choice to improve performance
|
||||
* in the cases where accidental duplicate calls don't matter. */
|
||||
final private class SingleFutureCache[A](compute: () => Fu[A], expireAfterMillis: Int) {
|
||||
|
||||
private var current: Fu[A] = fufail("SingleFutureCache.empty")
|
||||
private var expiresAt: Long = 0
|
||||
|
||||
def get: Fu[A] = {
|
||||
val now = nowMillis
|
||||
if (now > expiresAt) {
|
||||
expiresAt = now + expireAfterMillis
|
||||
current = compute()
|
||||
}
|
||||
current
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue