|
@@ -1,106 +0,0 @@
|
|
-package controllers
|
|
|
|
-
|
|
|
|
-import play.api.Play.current
|
|
|
|
-import play.api.db.DB
|
|
|
|
-import play.api.mvc._
|
|
|
|
-import play.api.libs.json.Json
|
|
|
|
-import java.util.concurrent._
|
|
|
|
-import scala.concurrent._
|
|
|
|
-import models.{World, Fortune}
|
|
|
|
-import utils._
|
|
|
|
-import scala.concurrent.Future
|
|
|
|
-
|
|
|
|
-import play.api.libs.concurrent.Execution.Implicits._
|
|
|
|
-import play.core.NamedThreadFactory
|
|
|
|
-
|
|
|
|
-object Application extends Controller {
|
|
|
|
-
|
|
|
|
- private val TestDatabaseRows = 10000
|
|
|
|
-
|
|
|
|
- private val partitionCount = current.configuration.getInt("db.default.partitionCount").getOrElse(2)
|
|
|
|
- private val maxConnections =
|
|
|
|
- partitionCount * current.configuration.getInt("db.default.maxConnectionsPerPartition").getOrElse(5)
|
|
|
|
- private val minConnections =
|
|
|
|
- partitionCount * current.configuration.getInt("db.default.minConnectionsPerPartition").getOrElse(5)
|
|
|
|
-
|
|
|
|
- private val tpe = new ThreadPoolExecutor(minConnections, maxConnections,
|
|
|
|
- 0L, TimeUnit.MILLISECONDS,
|
|
|
|
- new LinkedBlockingQueue[Runnable](),
|
|
|
|
- new NamedThreadFactory("dbEc"))
|
|
|
|
- private val dbEc = ExecutionContext.fromExecutorService(tpe)
|
|
|
|
-
|
|
|
|
- // If the thread-pool used by the database grows too large then our server
|
|
|
|
- // is probably struggling, and we should start dropping requests. Set
|
|
|
|
- // the max size of our queue something above the number of concurrent
|
|
|
|
- // connections that we need to handle.
|
|
|
|
- def isDbQueueTooBig: Boolean = tpe.getQueue.size() <= 1024
|
|
|
|
-
|
|
|
|
- def db = PredicatedAction(isDbQueueTooBig, ServiceUnavailable) {
|
|
|
|
- Action.async {
|
|
|
|
- getRandomWorlds(1).map { worlds =>
|
|
|
|
- Ok(Json.toJson(worlds.head))
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- def queries(countString: String) = PredicatedAction(isDbQueueTooBig, ServiceUnavailable) {
|
|
|
|
- Action.async {
|
|
|
|
- val n = parseCount(countString)
|
|
|
|
- getRandomWorlds(n).map { worlds =>
|
|
|
|
- Ok(Json.toJson(worlds))
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private def parseCount(s: String): Int = {
|
|
|
|
- try {
|
|
|
|
- val parsed = java.lang.Integer.parseInt(s, 10)
|
|
|
|
- parsed match {
|
|
|
|
- case i if i < 1 => 1
|
|
|
|
- case i if i > 500 => 500
|
|
|
|
- case i => i
|
|
|
|
- }
|
|
|
|
- } catch {
|
|
|
|
- case _: NumberFormatException => 1
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private def getRandomWorlds(n: Int): Future[Seq[World]] = Future {
|
|
|
|
- val random = ThreadLocalRandom.current()
|
|
|
|
- DB.withConnection { implicit connection =>
|
|
|
|
- for (_ <- 1 to n) yield {
|
|
|
|
- val randomId: Long = random.nextInt(TestDatabaseRows) + 1
|
|
|
|
- World.findById(randomId)
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }(dbEc)
|
|
|
|
-
|
|
|
|
- def fortunes() = PredicatedAction(isDbQueueTooBig, ServiceUnavailable) {
|
|
|
|
- Action.async {
|
|
|
|
- Future {
|
|
|
|
- val fortunes = Fortune.getAll()
|
|
|
|
- val extendedFortunes = Fortune(0.toLong, "Additional fortune added at request time.") +: fortunes
|
|
|
|
- Ok(views.html.fortune(extendedFortunes))
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- def update(countString: String) = PredicatedAction(isDbQueueTooBig, ServiceUnavailable) {
|
|
|
|
- Action.async {
|
|
|
|
- val n = parseCount(countString)
|
|
|
|
- Future {
|
|
|
|
- val random = ThreadLocalRandom.current()
|
|
|
|
- val worlds = DB.withConnection { implicit connection =>
|
|
|
|
- for(_ <- 1 to n) yield {
|
|
|
|
- val randomId: Long = random.nextInt(TestDatabaseRows) + 1
|
|
|
|
- val world = World.findById(random.nextInt(TestDatabaseRows) + 1)
|
|
|
|
- val updatedWorld = world.copy(randomNumber = random.nextInt(10000) + 1)
|
|
|
|
- World.updateRandom(updatedWorld)
|
|
|
|
- updatedWorld
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- Ok(Json.toJson(worlds)).withHeaders("Server" -> "Netty")
|
|
|
|
- }(dbEc)
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-}
|
|
|