Skip to content

Instantly share code, notes, and snippets.

@rossabaker
Created July 7, 2020 18:59
Show Gist options
  • Save rossabaker/2c2478a85a202d06c39abce2dccc3369 to your computer and use it in GitHub Desktop.
Save rossabaker/2c2478a85a202d06c39abce2dccc3369 to your computer and use it in GitHub Desktop.
import cats.effect._
import cats.implicits._
import javax.servlet._
import javax.servlet.annotation._
import java.util.concurrent._
import org.http4s._
import org.http4s.server._
import org.http4s.servlet._
import scala.concurrent.ExecutionContext.global
abstract class Bootstrap[F[_]] extends ServletContextListener {
implicit def F: ConcurrentEffect[F]
implicit def cs: ContextShift[F]
def appF: F[HttpApp[F]] = F.delay(HttpApp[F] { _ => Response[F](Status.Ok).withEntity("Hi!").pure[F] })
var pool: ExecutorService = _
override def contextInitialized(sce: ServletContextEvent): Unit = {
pool = Executors.newCachedThreadPool()
val ctx = sce.getServletContext
val blocker = Blocker.liftExecutorService(pool)
val f = appF.flatMap { app =>
val servlet = new AsyncHttp4sServlet[F](
app,
servletIo = BlockingServletIo(4096, blocker),
serviceErrorHandler = DefaultServiceErrorHandler
)
F.delay {
val reg = ctx.addServlet("example", servlet)
reg.addMapping("/")
reg.setAsyncSupported(true)
}
}
F.toIO(f).unsafeRunSync()
}
override def contextDestroyed(sce: ServletContextEvent): Unit = {
if (pool != null)
pool.shutdown()
}
}
@WebListener
class BootstrapIO extends Bootstrap[IO] {
val cs: ContextShift[IO] = IO.contextShift(global)
val F: ConcurrentEffect[IO] = IO.ioConcurrentEffect(cs)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment