mirror of
https://github.com/TheAnachronism/docspell.git
synced 2025-06-05 22:55:58 +00:00
Update http4s to 0.21.4
This commit is contained in:
parent
c9bfc50eb9
commit
75a66ecb86
13
modules/common/src/main/scala/docspell/common/Pools.scala
Normal file
13
modules/common/src/main/scala/docspell/common/Pools.scala
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
package docspell.common
|
||||||
|
|
||||||
|
import cats.effect._
|
||||||
|
import scala.concurrent.ExecutionContext
|
||||||
|
|
||||||
|
/** Captures thread pools to use in an application.
|
||||||
|
*/
|
||||||
|
case class Pools(
|
||||||
|
connectEC: ExecutionContext,
|
||||||
|
httpClientEC: ExecutionContext,
|
||||||
|
blocker: Blocker,
|
||||||
|
restEC: ExecutionContext
|
||||||
|
)
|
@ -4,6 +4,9 @@ import java.util.concurrent.atomic.AtomicLong
|
|||||||
import java.util.concurrent.{Executors, ThreadFactory}
|
import java.util.concurrent.{Executors, ThreadFactory}
|
||||||
import cats.effect._
|
import cats.effect._
|
||||||
import scala.concurrent._
|
import scala.concurrent._
|
||||||
|
import java.util.concurrent.ForkJoinPool
|
||||||
|
import java.util.concurrent.ForkJoinPool.ForkJoinWorkerThreadFactory
|
||||||
|
import java.util.concurrent.ForkJoinWorkerThread
|
||||||
|
|
||||||
object ThreadFactories {
|
object ThreadFactories {
|
||||||
|
|
||||||
@ -19,6 +22,18 @@ object ThreadFactories {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def ofNameFJ(prefix: String): ForkJoinWorkerThreadFactory =
|
||||||
|
new ForkJoinWorkerThreadFactory {
|
||||||
|
val tf = ForkJoinPool.defaultForkJoinWorkerThreadFactory
|
||||||
|
val counter = new AtomicLong(0)
|
||||||
|
|
||||||
|
def newThread(pool: ForkJoinPool): ForkJoinWorkerThread = {
|
||||||
|
val t = tf.newThread(pool)
|
||||||
|
t.setName(s"$prefix-${counter.getAndIncrement()}")
|
||||||
|
t
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
def executorResource[F[_]: Sync](
|
def executorResource[F[_]: Sync](
|
||||||
c: => ExecutionContextExecutorService
|
c: => ExecutionContextExecutorService
|
||||||
): Resource[F, ExecutionContextExecutorService] =
|
): Resource[F, ExecutionContextExecutorService] =
|
||||||
@ -38,4 +53,19 @@ object ThreadFactories {
|
|||||||
executorResource(
|
executorResource(
|
||||||
ExecutionContext.fromExecutorService(Executors.newFixedThreadPool(n, tf))
|
ExecutionContext.fromExecutorService(Executors.newFixedThreadPool(n, tf))
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def workSteal[F[_]: Sync](
|
||||||
|
n: Int,
|
||||||
|
tf: ForkJoinWorkerThreadFactory
|
||||||
|
): Resource[F, ExecutionContextExecutorService] =
|
||||||
|
executorResource(
|
||||||
|
ExecutionContext.fromExecutorService(
|
||||||
|
new ForkJoinPool(n, tf, null, true)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
def workSteal[F[_]: Sync](
|
||||||
|
tf: ForkJoinWorkerThreadFactory
|
||||||
|
): Resource[F, ExecutionContextExecutorService] =
|
||||||
|
workSteal[F](Runtime.getRuntime().availableProcessors() + 1, tf)
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ package docspell.joex
|
|||||||
|
|
||||||
import cats.effect._
|
import cats.effect._
|
||||||
import cats.effect.concurrent.Ref
|
import cats.effect.concurrent.Ref
|
||||||
|
import docspell.common.Pools
|
||||||
import docspell.joex.routes._
|
import docspell.joex.routes._
|
||||||
import org.http4s.server.blaze.BlazeServerBuilder
|
import org.http4s.server.blaze.BlazeServerBuilder
|
||||||
import org.http4s.implicits._
|
import org.http4s.implicits._
|
||||||
@ -11,8 +12,6 @@ import org.http4s.HttpApp
|
|||||||
import org.http4s.server.middleware.Logger
|
import org.http4s.server.middleware.Logger
|
||||||
import org.http4s.server.Router
|
import org.http4s.server.Router
|
||||||
|
|
||||||
import scala.concurrent.ExecutionContext
|
|
||||||
|
|
||||||
object JoexServer {
|
object JoexServer {
|
||||||
|
|
||||||
private case class App[F[_]](
|
private case class App[F[_]](
|
||||||
@ -23,15 +22,14 @@ object JoexServer {
|
|||||||
|
|
||||||
def stream[F[_]: ConcurrentEffect: ContextShift](
|
def stream[F[_]: ConcurrentEffect: ContextShift](
|
||||||
cfg: Config,
|
cfg: Config,
|
||||||
connectEC: ExecutionContext,
|
pools: Pools
|
||||||
clientEC: ExecutionContext,
|
|
||||||
blocker: Blocker
|
|
||||||
)(implicit T: Timer[F]): Stream[F, Nothing] = {
|
)(implicit T: Timer[F]): Stream[F, Nothing] = {
|
||||||
|
|
||||||
val app = for {
|
val app = for {
|
||||||
signal <- Resource.liftF(SignallingRef[F, Boolean](false))
|
signal <- Resource.liftF(SignallingRef[F, Boolean](false))
|
||||||
exitCode <- Resource.liftF(Ref[F].of(ExitCode.Success))
|
exitCode <- Resource.liftF(Ref[F].of(ExitCode.Success))
|
||||||
joexApp <- JoexAppImpl.create[F](cfg, signal, connectEC, clientEC, blocker)
|
joexApp <- JoexAppImpl
|
||||||
|
.create[F](cfg, signal, pools.connectEC, pools.httpClientEC, pools.blocker)
|
||||||
|
|
||||||
httpApp = Router(
|
httpApp = Router(
|
||||||
"/api/info" -> InfoRoutes(),
|
"/api/info" -> InfoRoutes(),
|
||||||
@ -46,7 +44,7 @@ object JoexServer {
|
|||||||
Stream
|
Stream
|
||||||
.resource(app)
|
.resource(app)
|
||||||
.flatMap(app =>
|
.flatMap(app =>
|
||||||
BlazeServerBuilder[F]
|
BlazeServerBuilder[F](pools.restEC)
|
||||||
.bindHttp(cfg.bind.port, cfg.bind.address)
|
.bindHttp(cfg.bind.port, cfg.bind.address)
|
||||||
.withHttpApp(app.httpApp)
|
.withHttpApp(app.httpApp)
|
||||||
.withoutBanner
|
.withoutBanner
|
||||||
|
@ -4,9 +4,8 @@ import cats.effect.{Blocker, ExitCode, IO, IOApp}
|
|||||||
import cats.implicits._
|
import cats.implicits._
|
||||||
|
|
||||||
import java.nio.file.{Files, Paths}
|
import java.nio.file.{Files, Paths}
|
||||||
import scala.concurrent.ExecutionContext
|
|
||||||
|
|
||||||
import docspell.common.{Banner, ThreadFactories}
|
import docspell.common.{Banner, Pools, ThreadFactories}
|
||||||
import org.log4s._
|
import org.log4s._
|
||||||
|
|
||||||
object Main extends IOApp {
|
object Main extends IOApp {
|
||||||
@ -16,6 +15,8 @@ object Main extends IOApp {
|
|||||||
ThreadFactories.cached[IO](ThreadFactories.ofName("docspell-joex-blocking"))
|
ThreadFactories.cached[IO](ThreadFactories.ofName("docspell-joex-blocking"))
|
||||||
val connectEC =
|
val connectEC =
|
||||||
ThreadFactories.fixed[IO](5, ThreadFactories.ofName("docspell-joex-dbconnect"))
|
ThreadFactories.fixed[IO](5, ThreadFactories.ofName("docspell-joex-dbconnect"))
|
||||||
|
val restserverEC =
|
||||||
|
ThreadFactories.workSteal[IO](ThreadFactories.ofNameFJ("docspell-joex-server"))
|
||||||
|
|
||||||
def run(args: List[String]) = {
|
def run(args: List[String]) = {
|
||||||
args match {
|
args match {
|
||||||
@ -52,19 +53,14 @@ object Main extends IOApp {
|
|||||||
cec <- connectEC
|
cec <- connectEC
|
||||||
bec <- blockingEC
|
bec <- blockingEC
|
||||||
blocker = Blocker.liftExecutorService(bec)
|
blocker = Blocker.liftExecutorService(bec)
|
||||||
} yield Pools(cec, bec, blocker)
|
rec <- restserverEC
|
||||||
|
} yield Pools(cec, bec, blocker, rec)
|
||||||
pools.use(p =>
|
pools.use(p =>
|
||||||
JoexServer
|
JoexServer
|
||||||
.stream[IO](cfg, p.connectEC, p.clientEC, p.blocker)
|
.stream[IO](cfg, p)
|
||||||
.compile
|
.compile
|
||||||
.drain
|
.drain
|
||||||
.as(ExitCode.Success)
|
.as(ExitCode.Success)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
case class Pools(
|
|
||||||
connectEC: ExecutionContext,
|
|
||||||
clientEC: ExecutionContext,
|
|
||||||
blocker: Blocker
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
@ -3,10 +3,9 @@ package docspell.restserver
|
|||||||
import cats.effect._
|
import cats.effect._
|
||||||
import cats.implicits._
|
import cats.implicits._
|
||||||
|
|
||||||
import scala.concurrent.ExecutionContext
|
|
||||||
import java.nio.file.{Files, Paths}
|
import java.nio.file.{Files, Paths}
|
||||||
|
|
||||||
import docspell.common.{Banner, ThreadFactories}
|
import docspell.common.{Banner, Pools, ThreadFactories}
|
||||||
import org.log4s._
|
import org.log4s._
|
||||||
|
|
||||||
object Main extends IOApp {
|
object Main extends IOApp {
|
||||||
@ -16,6 +15,8 @@ object Main extends IOApp {
|
|||||||
ThreadFactories.cached[IO](ThreadFactories.ofName("docspell-restserver-blocking"))
|
ThreadFactories.cached[IO](ThreadFactories.ofName("docspell-restserver-blocking"))
|
||||||
val connectEC =
|
val connectEC =
|
||||||
ThreadFactories.fixed[IO](5, ThreadFactories.ofName("docspell-dbconnect"))
|
ThreadFactories.fixed[IO](5, ThreadFactories.ofName("docspell-dbconnect"))
|
||||||
|
val restserverEC =
|
||||||
|
ThreadFactories.workSteal[IO](ThreadFactories.ofNameFJ("docspell-restserver"))
|
||||||
|
|
||||||
def run(args: List[String]) = {
|
def run(args: List[String]) = {
|
||||||
args match {
|
args match {
|
||||||
@ -51,21 +52,16 @@ object Main extends IOApp {
|
|||||||
cec <- connectEC
|
cec <- connectEC
|
||||||
bec <- blockingEC
|
bec <- blockingEC
|
||||||
blocker = Blocker.liftExecutorService(bec)
|
blocker = Blocker.liftExecutorService(bec)
|
||||||
} yield Pools(cec, bec, blocker)
|
rec <- restserverEC
|
||||||
|
} yield Pools(cec, bec, blocker, rec)
|
||||||
|
|
||||||
logger.info(s"\n${banner.render("***>")}")
|
logger.info(s"\n${banner.render("***>")}")
|
||||||
pools.use(p =>
|
pools.use(p =>
|
||||||
RestServer
|
RestServer
|
||||||
.stream[IO](cfg, p.connectEC, p.clientEC, p.blocker)
|
.stream[IO](cfg, p)
|
||||||
.compile
|
.compile
|
||||||
.drain
|
.drain
|
||||||
.as(ExitCode.Success)
|
.as(ExitCode.Success)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
case class Pools(
|
|
||||||
connectEC: ExecutionContext,
|
|
||||||
clientEC: ExecutionContext,
|
|
||||||
blocker: Blocker
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ package docspell.restserver
|
|||||||
|
|
||||||
import cats.effect._
|
import cats.effect._
|
||||||
import cats.data.{Kleisli, OptionT}
|
import cats.data.{Kleisli, OptionT}
|
||||||
|
import docspell.common.Pools
|
||||||
import docspell.backend.auth.AuthToken
|
import docspell.backend.auth.AuthToken
|
||||||
import docspell.restserver.routes._
|
import docspell.restserver.routes._
|
||||||
import docspell.restserver.webapp._
|
import docspell.restserver.webapp._
|
||||||
@ -13,20 +14,17 @@ import org.http4s.server.Router
|
|||||||
import org.http4s.server.blaze.BlazeServerBuilder
|
import org.http4s.server.blaze.BlazeServerBuilder
|
||||||
import org.http4s.server.middleware.Logger
|
import org.http4s.server.middleware.Logger
|
||||||
|
|
||||||
import scala.concurrent.ExecutionContext
|
|
||||||
|
|
||||||
object RestServer {
|
object RestServer {
|
||||||
|
|
||||||
def stream[F[_]: ConcurrentEffect](
|
def stream[F[_]: ConcurrentEffect](
|
||||||
cfg: Config,
|
cfg: Config,
|
||||||
connectEC: ExecutionContext,
|
pools: Pools
|
||||||
httpClientEc: ExecutionContext,
|
|
||||||
blocker: Blocker
|
|
||||||
)(implicit T: Timer[F], CS: ContextShift[F]): Stream[F, Nothing] = {
|
)(implicit T: Timer[F], CS: ContextShift[F]): Stream[F, Nothing] = {
|
||||||
|
|
||||||
val templates = TemplateRoutes[F](blocker, cfg)
|
val templates = TemplateRoutes[F](pools.blocker, cfg)
|
||||||
val app = for {
|
val app = for {
|
||||||
restApp <- RestAppImpl.create[F](cfg, connectEC, httpClientEc, blocker)
|
restApp <- RestAppImpl
|
||||||
|
.create[F](cfg, pools.connectEC, pools.httpClientEC, pools.blocker)
|
||||||
httpApp = Router(
|
httpApp = Router(
|
||||||
"/api/info" -> routes.InfoRoutes(),
|
"/api/info" -> routes.InfoRoutes(),
|
||||||
"/api/v1/open/" -> openRoutes(cfg, restApp),
|
"/api/v1/open/" -> openRoutes(cfg, restApp),
|
||||||
@ -34,7 +32,7 @@ object RestServer {
|
|||||||
securedRoutes(cfg, restApp, token)
|
securedRoutes(cfg, restApp, token)
|
||||||
},
|
},
|
||||||
"/api/doc" -> templates.doc,
|
"/api/doc" -> templates.doc,
|
||||||
"/app/assets" -> WebjarRoutes.appRoutes[F](blocker),
|
"/app/assets" -> WebjarRoutes.appRoutes[F](pools.blocker),
|
||||||
"/app" -> templates.app,
|
"/app" -> templates.app,
|
||||||
"/" -> redirectTo("/app")
|
"/" -> redirectTo("/app")
|
||||||
).orNotFound
|
).orNotFound
|
||||||
@ -46,7 +44,7 @@ object RestServer {
|
|||||||
Stream
|
Stream
|
||||||
.resource(app)
|
.resource(app)
|
||||||
.flatMap(httpApp =>
|
.flatMap(httpApp =>
|
||||||
BlazeServerBuilder[F]
|
BlazeServerBuilder[F](pools.restEC)
|
||||||
.bindHttp(cfg.bind.port, cfg.bind.address)
|
.bindHttp(cfg.bind.port, cfg.bind.address)
|
||||||
.withHttpApp(httpApp)
|
.withHttpApp(httpApp)
|
||||||
.withoutBanner
|
.withoutBanner
|
||||||
|
@ -16,7 +16,7 @@ object Dependencies {
|
|||||||
val FlywayVersion = "6.4.0"
|
val FlywayVersion = "6.4.0"
|
||||||
val Fs2Version = "2.3.0"
|
val Fs2Version = "2.3.0"
|
||||||
val H2Version = "1.4.200"
|
val H2Version = "1.4.200"
|
||||||
val Http4sVersion = "0.21.3"
|
val Http4sVersion = "0.21.4"
|
||||||
val Icu4jVersion = "67.1"
|
val Icu4jVersion = "67.1"
|
||||||
val JsoupVersion = "1.13.1"
|
val JsoupVersion = "1.13.1"
|
||||||
val KindProjectorVersion = "0.10.3"
|
val KindProjectorVersion = "0.10.3"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user