【发布时间】:2020-07-04 23:35:54
【问题描述】:
我正在尝试在码头上运行基于http4s 的网络应用程序。 http4s库提供AsyncHttp4sServlet[IO]类来扩展,我使用如下:
class UserSvcServlet
extends AsyncHttp4sServlet[IO](
service = UserSvcServer.start,
servletIo = BlockingServletIo(4096, Blocker.liftExecutorService(Executors.newCachedThreadPool())),
serviceErrorHandler = DefaultServiceErrorHandler
)
正如您在 service 属性中看到的,我提供的 http 服务具有以下实现:
def start[F[_]: ConcurrentEffect: ContextShift: Sync: Timer]: HttpApp[F] =
for {
a <- EnvironmentLoader.db.load[F].map(create_transactor)
b <- EnvironmentLoader.cors.load[F].map(origin)
http = Logger.httpApp(true, true)(CORS(UserRoutes(UserProgram(LiveUserQuery.make(a))).routes, b).orNotFound)
} yield http
start 方法应该返回 HttpApp[F],但不幸的是 for 块返回 F[Http[F]]。但是最后F 将是IO 类型。
这里是HttpApp[F]的定义:
type Http[F[_], G[_]] = Kleisli[F, Request[G], Response[G]]
EnvironmentLoader.db.load[F].map(create_transactor) 和 EnvironmentLoader.cors.load[F].map(origin) 都在 F 的上下文中,它们加载环境变量。对于加载环境变量,我使用库https://cir.is/。
我知道,不可能将Http[F] 脱离上下文F。我必须在这里重组代码以使其工作吗?
更新
一种可能的解决方法是:
class UserSvcServlet
extends AsyncHttp4sServlet[IO](
service = UserSvcServer.start[IO].unsafeRunSync(),
servletIo = BlockingServletIo(4096, Blocker.liftExecutorService(Executors.newCachedThreadPool())),
serviceErrorHandler = DefaultServiceErrorHandler
)
虽然很丑,但是很管用。
【问题讨论】:
标签: scala servlets scala-cats http4s