diff --git a/src/main/resources/reference.conf b/src/main/resources/reference.conf index 27e30c7..1abb474 100644 --- a/src/main/resources/reference.conf +++ b/src/main/resources/reference.conf @@ -61,4 +61,13 @@ me.arcanis.ffxivbis { max-count = 60 } } + + default-dispatcher { + type = Dispatcher + executor = "thread-pool-executor" + thread-pool-executor { + fixed-pool-size = 16 + } + throughput = 1 + } } diff --git a/src/main/resources/swagger-info/description.md b/src/main/resources/swagger-info/description.md index 5309dd1..39647dc 100644 --- a/src/main/resources/swagger-info/description.md +++ b/src/main/resources/swagger-info/description.md @@ -3,7 +3,7 @@ REST json API description to interact with FFXIVBiS service. # Basic workflow * Create party using `PUT /api/v1/party` endpoint. It consumes username and password of administrator (which can't be restored). As the result it returns unique id of created party. -* Create new users which have access to this party. Note that user is belong to specific party id and in scope of the specified party it must be unique. +* Create new users which have access to this party. Note that user belongs to specific party id and in scope of the specified party it must be unique. * Add players with their best in slot sets (probably by using ariyala links). * Add loot items if any. * By using `PUT /api/v1/party/{partyId}/loot` API find players which are better for the specified loot. diff --git a/src/main/scala/me/arcanis/ffxivbis/http/api/v1/TypesEndpoint.scala b/src/main/scala/me/arcanis/ffxivbis/http/api/v1/TypesEndpoint.scala index 87c350e..f3c97ec 100644 --- a/src/main/scala/me/arcanis/ffxivbis/http/api/v1/TypesEndpoint.scala +++ b/src/main/scala/me/arcanis/ffxivbis/http/api/v1/TypesEndpoint.scala @@ -40,7 +40,7 @@ class TypesEndpoint(config: Config) extends JsonSupport { def getJobs: Route = path("types" / "jobs") { get { - complete(Job.available.map(_.toString)) + complete(Job.availableWithAnyJob.map(_.toString)) } } diff --git a/src/main/scala/me/arcanis/ffxivbis/http/view/LootSuggestView.scala b/src/main/scala/me/arcanis/ffxivbis/http/view/LootSuggestView.scala index 25a49db..8891f85 100644 --- a/src/main/scala/me/arcanis/ffxivbis/http/view/LootSuggestView.scala +++ b/src/main/scala/me/arcanis/ffxivbis/http/view/LootSuggestView.scala @@ -14,7 +14,7 @@ import akka.http.scaladsl.server.Directives._ import akka.http.scaladsl.server.Route import akka.util.Timeout import me.arcanis.ffxivbis.http.{Authorization, LootHelper} -import me.arcanis.ffxivbis.models.{Piece, PlayerIdWithCounters} +import me.arcanis.ffxivbis.models.{Job, Piece, PlayerIdWithCounters} import scala.concurrent.{ExecutionContext, Future} import scala.util.{Failure, Success, Try} @@ -43,9 +43,9 @@ class LootSuggestView(override val storage: ActorRef)(implicit timeout: Timeout) extractExecutionContext { implicit executionContext => authenticateBasicBCrypt(s"party $partyId", authGet(partyId)) { _ => post { - formFields("piece".as[String], "is_tome".as[String].?) { (piece, maybeTome) => + formFields("piece".as[String], "job".as[String], "is_tome".as[String].?) { (piece, job, maybeTome) => import me.arcanis.ffxivbis.utils.Implicits._ - val maybePiece = Try(Piece(piece, maybeTome)).toOption + val maybePiece = Try(Piece(piece, maybeTome, Job.withName(job))).toOption onComplete(suggestLootCall(partyId, maybePiece)) { case Success(players) => @@ -90,6 +90,8 @@ object LootSuggestView { form(action:=s"/party/$partyId/suggest", method:="post")( select(name:="piece", id:="piece", title:="piece") (for (piece <- Piece.available) yield option(piece)), + select(name:="job", id:="job", title:="job") + (for (job <- Job.availableWithAnyJob) yield option(job.toString)), input(name:="is_tome", id:="is_tome", title:="is tome", `type`:="checkbox"), label(`for`:="is_tome")("is tome gear"), input(name:="suggest", id:="suggest", `type`:="submit", value:="suggest") diff --git a/src/main/scala/me/arcanis/ffxivbis/http/view/LootView.scala b/src/main/scala/me/arcanis/ffxivbis/http/view/LootView.scala index 1f63aa5..2b21a88 100644 --- a/src/main/scala/me/arcanis/ffxivbis/http/view/LootView.scala +++ b/src/main/scala/me/arcanis/ffxivbis/http/view/LootView.scala @@ -113,7 +113,7 @@ object LootView { th("is tome"), th("") ), - for (player <- party; piece <- player.bis.pieces) yield tr( + for (player <- party; piece <- player.loot) yield tr( td(`class`:="include_search")(player.playerId.toString), td(`class`:="include_search")(piece.piece), td(piece.isTomeToString), diff --git a/src/main/scala/me/arcanis/ffxivbis/models/Job.scala b/src/main/scala/me/arcanis/ffxivbis/models/Job.scala index ce649c3..716084d 100644 --- a/src/main/scala/me/arcanis/ffxivbis/models/Job.scala +++ b/src/main/scala/me/arcanis/ffxivbis/models/Job.scala @@ -98,6 +98,7 @@ object Job { lazy val available: Seq[Job] = Seq(PLD, WAR, DRK, GNB, WHM, SCH, AST, MNK, DRG, NIN, SAM, BRD, MCH, DNC, BLM, SMN, RDM) + lazy val availableWithAnyJob: Seq[Job] = available.prepended(AnyJob) def withName(job: String): Job.Job = available.find(_.toString == job.toUpperCase).getOrElse(AnyJob) } diff --git a/src/main/scala/me/arcanis/ffxivbis/service/Ariyala.scala b/src/main/scala/me/arcanis/ffxivbis/service/Ariyala.scala index 02e6c65..d22df59 100644 --- a/src/main/scala/me/arcanis/ffxivbis/service/Ariyala.scala +++ b/src/main/scala/me/arcanis/ffxivbis/service/Ariyala.scala @@ -34,7 +34,8 @@ class Ariyala extends Actor with StrictLogging { private val http = Http()(context.system) implicit private val materializer: ActorMaterializer = ActorMaterializer() - implicit private val executionContext: ExecutionContext = context.dispatcher + implicit private val executionContext: ExecutionContext = + context.system.dispatchers.lookup("me.arcanis.ffxivbis.default-dispatcher") override def receive: Receive = { case GetBiS(link, job) => @@ -42,6 +43,11 @@ class Ariyala extends Actor with StrictLogging { get(link, job).map(BiS(_)).pipeTo(client) } + override def postStop(): Unit = { + http.shutdownAllConnectionPools() + super.postStop() + } + private def get(link: String, job: Job.Job): Future[Seq[Piece]] = { val id = Paths.get(link).normalize.getFileName.toString val uri = Uri(ariyalaUrl) diff --git a/src/main/scala/me/arcanis/ffxivbis/service/PartyService.scala b/src/main/scala/me/arcanis/ffxivbis/service/PartyService.scala index d3bc22c..0cfa41e 100644 --- a/src/main/scala/me/arcanis/ffxivbis/service/PartyService.scala +++ b/src/main/scala/me/arcanis/ffxivbis/service/PartyService.scala @@ -23,7 +23,8 @@ class PartyService(storage: ActorRef) extends Actor with StrictLogging { private val cacheTimeout: FiniteDuration = context.system.settings.config.getDuration("me.arcanis.ffxivbis.settings.cache-timeout") - implicit private val executionContext: ExecutionContext = context.dispatcher + implicit private val executionContext: ExecutionContext = + context.system.dispatchers.lookup("me.arcanis.ffxivbis.default-dispatcher") implicit private val timeout: Timeout = context.system.settings.config.getDuration("me.arcanis.ffxivbis.settings.request-timeout") diff --git a/src/main/scala/me/arcanis/ffxivbis/service/impl/DatabaseImpl.scala b/src/main/scala/me/arcanis/ffxivbis/service/impl/DatabaseImpl.scala index d68cbd2..74e4e55 100644 --- a/src/main/scala/me/arcanis/ffxivbis/service/impl/DatabaseImpl.scala +++ b/src/main/scala/me/arcanis/ffxivbis/service/impl/DatabaseImpl.scala @@ -18,7 +18,8 @@ class DatabaseImpl extends Database with DatabaseBiSHandler with DatabaseLootHandler with DatabasePartyHandler with DatabaseUserHandler { - implicit val executionContext: ExecutionContext = context.dispatcher + implicit val executionContext: ExecutionContext = + context.system.dispatchers.lookup("me.arcanis.ffxivbis.default-dispatcher") val profile = new DatabaseProfile(executionContext, context.system.settings.config) override def receive: Receive = diff --git a/src/test/scala/me/arcanis/ffxivbis/http/api/v1/TypesEndpointTest.scala b/src/test/scala/me/arcanis/ffxivbis/http/api/v1/TypesEndpointTest.scala index 859c87a..802ab0e 100644 --- a/src/test/scala/me/arcanis/ffxivbis/http/api/v1/TypesEndpointTest.scala +++ b/src/test/scala/me/arcanis/ffxivbis/http/api/v1/TypesEndpointTest.scala @@ -23,7 +23,7 @@ class TypesEndpointTest extends WordSpec "return all available jobs" in { Get("/types/jobs") ~> route ~> check { status shouldEqual StatusCodes.OK - responseAs[Seq[String]] shouldEqual Job.available.map(_.toString) + responseAs[Seq[String]] shouldEqual Job.availableWithAnyJob.map(_.toString) } }