我正在尝试在码头上运行基于http4s的 webapp 。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
)
它很丑,但它有效。