-
Notifications
You must be signed in to change notification settings - Fork 6
ChildProcess -> fs2 Processes #200
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
I tried to get a native tracer to link. Here's the diff: diff --git a/build.sbt b/build.sbt
index e98ee533c..a94525142 100644
--- a/build.sbt
+++ b/build.sbt
@@ -29,18 +29,18 @@ inThisBuild(
)
val V = new {
- val scala = "3.3.3"
+ val scala = "3.3.5"
val scribe = "3.13.1"
val upickle = "2.0.0"
val cats = "2.10.0"
val jsonrpclib = "0.0.7"
- val fs2 = "3.10.0"
- val http4s = "0.23.26"
+ val fs2 = "3.11.0"
+ val http4s = "0.23.30"
val laminar = "0.14.5"
val decline = "2.4.1"
val jsoniter = "2.20.3"
val weaver = "0.8.4"
- val circe = "0.14.5"
+ val circe = "0.14.8"
val http4sJdkClient = "0.9.1"
val organizeImports = "0.6.0"
val fansi = "0.4.0"
@@ -253,7 +253,8 @@ lazy val tracer = projectMatrix
libraryDependencies += "org.http4s" %%% "http4s-dsl" % V.http4s,
libraryDependencies += "com.monovore" %%% "decline" % V.decline,
libraryDependencies += "com.outr" %%% "scribe-cats" % V.scribe,
- libraryDependencies += "com.indoorvivants.detective" %% "platform" % V.detective,
+ libraryDependencies += "com.indoorvivants.detective" %%% "platform" % V.detective,
+ libraryDependencies += "io.chrisdavenport" %%% "crossplatformioapp" % "0.1.0",
Compile / doc / sources := Seq.empty,
// embedding frontend in backend's resources
Compile / resourceGenerators += {
@@ -289,6 +290,15 @@ lazy val tracer = projectMatrix
}
)
.jvmPlatform(V.scalaVersions)
+ .nativePlatform(
+ V.scalaVersions,
+ Seq(
+ libraryDependencies ++= Seq(
+ "com.armanbilge" %%% "epollcat" % "0.1.6"
+ ),
+ nativeConfig ~= (_.withEmbedResources(true))
+ )
+ )
import org.scalajs.linker.interface.Report
lazy val frontendJS = tracerFrontend.js(V.scala)
@@ -332,6 +342,7 @@ lazy val tracerShared = projectMatrix
)
.jsPlatform(V.scalaVersions)
.jvmPlatform(V.scalaVersions)
+ .nativePlatform(V.scalaVersions)
val scalafixRules = Seq(
"OrganizeImports",
@@ -411,14 +422,14 @@ import sbtwelcome.*
logo :=
raw"""
- | _ _ _
- | | | | | (_)
- | | | __ _ _ __ __ _ ___ _ _ ___| |_ _ _ __ ___
+ | _ _ _
+ | | | | | (_)
+ | | | __ _ _ __ __ _ ___ _ _ ___| |_ _ _ __ ___
| | | / _` | '_ \ / _` |/ _ \| | | / __| __| | '_ \ / _ \
| | |___| (_| | | | | (_| | (_) | |_| \__ \ |_| | | | | __/
| |______\__,_|_| |_|\__, |\___/ \__,_|___/\__|_|_| |_|\___|
- | __/ |
- | |___/
+ | __/ |
+ | |___/
|
|${version.value}
|
diff --git a/modules/tracer/backend/src/main/scala/main.scala b/modules/tracer/backend/src/main/scala/main.scala
index 4b695430e..96090ea19 100644
--- a/modules/tracer/backend/src/main/scala/main.scala
+++ b/modules/tracer/backend/src/main/scala/main.scala
@@ -33,8 +33,9 @@ import langoustine.lsp.all.ShowMessageParams
import com.github.plokhotnyuk.jsoniter_scala.core.*
import fs2.concurrent.Channel
import jsonrpclib.Message
+import io.chrisdavenport.crossplatformioapp.CrossPlatformIOApp
-object LangoustineTracer extends IOApp:
+object LangoustineTracer extends CrossPlatformIOApp:
def run(args: List[String]): IO[ExitCode] =
Config.command.parse(args, sys.env) match
case Left(help) =>
diff --git a/modules/tracer/backend/src/main/scala/routes.static.scala b/modules/tracer/backend/src/main/scala/routes.static.scala
index 374b7273c..f6194ab0c 100644
--- a/modules/tracer/backend/src/main/scala/routes.static.scala
+++ b/modules/tracer/backend/src/main/scala/routes.static.scala
@@ -19,32 +19,49 @@ package langoustine.tracer
import org.http4s.*
import cats.effect.*
import org.http4s.dsl.io.*
-import java.nio.file.Paths
+import fs2.io.file.Path
+import cats.data.OptionT
object Static:
- def routes =
- val indexHtml = StaticFile
- .fromResource[IO](
- "assets/index.html",
+ def routes: HttpRoutes[IO] =
+ val indexHtml =
+ // StaticFile.
+ fromResource(
+ Path("assets") / "index.html",
None,
preferGzipped = true
)
- .getOrElseF(NotFound())
+ .getOrElseF(NotFound())
HttpRoutes.of[IO] {
case req @ GET -> Root / "assets" / filename
if filename.endsWith(".js") ||
filename.endsWith(".js.map") ||
filename.endsWith(".svg") =>
- StaticFile
- .fromResource[IO](
- Paths.get("assets", filename).toString,
- Some(req),
- preferGzipped = true
- )
+ // StaticFile.
+ fromResource(
+ Path("assets") / filename,
+ Some(req),
+ preferGzipped = true
+ )
.getOrElseF(NotFound())
case req @ GET -> Root => indexHtml
case req if req.method == GET => indexHtml
}
end routes
+
+ // https://github.com/http4s/http4s/issues/7648
+ private def fromResource(
+ path: Path,
+ request: Option[Request[IO]],
+ preferGzipped: Boolean = false
+ ): OptionT[IO, Response[IO]] =
+ OptionT.pure {
+ Response(status = Status.Ok).withEntity {
+ fs2.io.readClassResource[IO, Static.type](
+ name = s"/${path.toString}",
+ chunkSize = 4192
+ )
+ }
+ }
end Static
So basically we need http4s/http4s#7648 (or the local workaround), crossplatformioapp/epollcat, and the only part that was missing for me was the libcrypto library. Update: well, I got it to link and start locally, and it even prints the port of the server after launching, but unfortunately none of the HTTP APIs work. I suppose it has to do with blocking in stdio streams of the tracer itself, combined with the process run. Given SN 0.4 doesn't support multithreading, I guess we'll have to wait with this dream until 0.5 gets supported in Cats Effect and the rest of the stack... or maybe the polling system in CE will allow fs2.io to work without blocking actual threads? |
@@ -107,7 +114,6 @@ def Trace( | |||
.through(inBytes.publish) | |||
.onFinalize( | |||
Logging.info("process stdin finished, shutting down tracer") *> | |||
child.terminate *> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tests pass, but I feel like we may be missing something if this isn't called. The fs2 process API doesn't actually have a method for killing the process, guess you have to somehow provoke the resource to exit early instead.
How would I confirm whether this is fine as-is?
Quick attempt to replace the homegrown
ChildProcess
with thefs2.io.process
API. It's cross-platform, so with a few more tricks we might have a Native/Node-based tracer backend.