#scala #bazel #fs2 #http4s #zio
#scala #bazel #fs2 #http4s #zio
Вопрос:
Я пытаюсь создать сервис, который объединяет ZIO и http4s.
Отправной точкой является этот пример (он использует zio 1.0.1, http4s 0.21.3, scala 2.12.11)
Я смог создать приведенный ниже код без каких-либо проблем с использованием sbt
, но столкнулся с проблемами при попытке сборки с помощью Bazel:
import org.http4s.HttpRoutes
import org.http4s.dsl.Http4sDsl
import org.http4s.implicits._
import org.http4s.server.blaze._
import zio._
import zio.interop.catz._
import zio.interop.catz.implicits._
object Hello1 extends App {
val server: ZIO[ZEnv, Throwable, Unit] = ZIO.runtime[ZEnv]
.flatMap {
implicit rts =>
BlazeServerBuilder[Task]
.bindHttp(8080, "localhost")
.withHttpApp(Hello1Service.service)
.serve
.compile
.drain
}
def run(args: List[String]) =
server.exitCode
}
Sbt доволен, но когда я создаю это с помощью Bazel:
[Error] analytics/test-endpoint/Hello1.scala:20 could not find implicit value for parameter compiler: fs2.Stream.Compiler[[x]zio.ZIO[Any,Throwable,x],G]
О настройке bazel: я использую rules_scala
from higherkindness с BUILD
файлом, который выглядит как:
scala_binary(
name = "endpoint-bin",
srcs = ["Hello1.scala", "Hello1Service.scala"],
deps = [
"//3rdparty/jvm/default/org/http4s:http4s_dsl",
"//3rdparty/jvm/default/org/http4s:http4s_blaze_server",
"//3rdparty/jvm/default/dev/zio:zio",
"//3rdparty/jvm/default/dev/zio:zio_interop_cats",
"//3rdparty/jvm/default/org/typelevel:cats_effect",
],
)
Я не слишком хорошо осведомлен, когда дело доходит до имплицитов, и мне было интересно, какая часть «волшебного соуса» отсутствует, чтобы заставить это работать в Bazel. Пока у меня есть две гипотезы:
- Я пропустил зависимость, которую мне нужно где-то явно указать, и она находится в пути к классу при создании с помощью sbt, но отсутствует в Bazel
- все это зависит от макросов, которые, как я знаю, могут быть проблематичными в моей настройке
Следовательно, основной вопрос, который у меня есть: может ли кто-нибудь пролить свет на происходящую магию, которая позволяет компилятору найти правильное неявное значение для передачи compile
в примере кода выше?
Комментарии:
1. Перечислите библиотеки, флаги компилятора и плагины компилятора в обеих настройках и сравните их. Поскольку это 2.12, это может быть что-то столь же глупое, как отсутствие
-Ypartial-unification
.2. Посмотрев несколько минут на то, как я мог бы перечислить параметры scalac, переданные Bazel, я просто попытался добавить
scalacoptions = "-Ypartial-unification"
в правило и …. это сработало. Большое спасибо. Если вы напишете это в ответ, я буду более чем счастлив принять его.
Ответ №1:
Добавить -Ypartial-unification
в scalacOptions
. Отсутствие этого флага является основным нарушителем в Cats, Scalaz, ZIO и коде с высоким уровнем типов в целом. Или, если вы можете, перейдите на 2.13, где поведение этого флага было изменено, чтобы быть всегда включенным (а сам флаг удален).
Комментарии:
1. Спасибо за этот неожиданный ответ. Экосистема scala на Bazel, к сожалению, еще не полностью готова к версии 2.13 :(.
2. Если вы сами не добавили этот флаг в sbt, я предполагаю, что это был какой-то плагин sbt, такой как sbt-tpolecat. Вот почему я предложил посмотреть на флаги — они могут изменить поведение, но они могут быть добавлены не вами лично. И тогда все запутывается.