Migrate from Blaze to Ember

This commit is contained in:
Guntis Smaukstelis
2023-05-17 01:20:01 +03:00
parent 590757183a
commit affc2e0d93
5 changed files with 44 additions and 27 deletions
+4 -3
View File
@@ -8,13 +8,14 @@ lazy val root = (project in file("."))
Compile / mainClass := Some("server.Main") Compile / mainClass := Some("server.Main")
) )
val http4sVersion = "0.23.16" val http4sVersion = "0.23.18"
val circeVersion = "0.14.1" val circeVersion = "0.14.1"
libraryDependencies ++= Seq( libraryDependencies ++= Seq(
"org.http4s" %% "http4s-dsl" % http4sVersion, "org.http4s" %% "http4s-dsl" % http4sVersion,
"org.http4s" %% "http4s-blaze-server" % "0.23.9", "org.http4s" %% "http4s-server" % http4sVersion,
"org.http4s" %% "http4s-blaze-client" % "0.23.13", "org.http4s" %% "http4s-ember-server" % http4sVersion,
"org.http4s" %% "http4s-ember-client" % http4sVersion,
"org.http4s" %% "http4s-circe" % http4sVersion, "org.http4s" %% "http4s-circe" % http4sVersion,
"ch.qos.logback" % "logback-classic" % "1.2.9", "ch.qos.logback" % "logback-classic" % "1.2.9",
+2 -2
View File
@@ -3,9 +3,9 @@ package fetch
import cats.effect._ import cats.effect._
import cats.implicits._ import cats.implicits._
import org.http4s._ import org.http4s._
import org.http4s.blaze.client.BlazeClientBuilder
import org.http4s.client.Client import org.http4s.client.Client
import org.http4s.headers.Authorization import org.http4s.headers.Authorization
import org.http4s.ember.client.EmberClientBuilder
import pureconfig._ import pureconfig._
import pureconfig.generic.auto._ import pureconfig.generic.auto._
@@ -45,7 +45,7 @@ object FetchService {
private def fetchFiles(fileNames: List[String]): IO[List[Either[Throwable, (String, String)]]] = { private def fetchFiles(fileNames: List[String]): IO[List[Either[Throwable, (String, String)]]] = {
val IOUrls = baseUrl.map(baseUrl => fileNames.map(baseUrl / _)) val IOUrls = baseUrl.map(baseUrl => fileNames.map(baseUrl / _))
BlazeClientBuilder[IO](global).resource.use { client => EmberClientBuilder.default[IO].build.use { client =>
IOUrls.flatMap(_.traverse(url => makeRequest(client, url))) IOUrls.flatMap(_.traverse(url => makeRequest(client, url)))
} }
} }
+7 -6
View File
@@ -1,22 +1,23 @@
package server package server
import cats.effect._ import cats.effect._
import cats.implicits.catsSyntaxTuple2Parallel
import db.DBService import db.DBService
import fetch.{FetchService, FileNameService} import fetch.{FetchService, FileNameService}
import fs2.Stream
object Main extends IOApp { object Main extends IOApp {
def run(args: List[String]): IO[ExitCode] = { def run(args: List[String]): IO[ExitCode] = {
val fetchTask = FileNameService.generateCurrentHour.flatMap(FetchService.fetchSingleFile) val fetchTask = FileNameService.generateCurrentHour.flatMap(FetchService.fetchSingleFile)
Stream( val scheduler = Scheduler.scheduleTask(fetchTask)
Server.run,
Scheduler.scheduleTask(fetchTask)
.evalMap { case (name, content) => .evalMap { case (name, content) =>
IO(println(s"fetched: $name")) *> IO(println(s"fetched: $name")) *>
DBService.save(name, content).attempt.flatMap { DBService.save(name, content).attempt.flatMap {
case Right(savedName) => IO(println(s"File saved: $savedName")) case Right(savedName) => IO(println(s"File saved: $savedName"))
case Left(err) => IO(println(s"Error: $err")) case Left(err) => IO(println(s"Error: $err"))
} }
} }.compile.drain // Convert Stream[IO, Unit] to IO[Unit]
).parJoinUnbounded.compile.drain.as(ExitCode.Success)
val server = Server.run // This is an IO[Server]
(server, scheduler).parMapN((_, _) => ExitCode.Success)
} }
} }
+23 -8
View File
@@ -2,6 +2,7 @@ package server
import cats.effect._ import cats.effect._
import cats.implicits.toTraverseOps import cats.implicits.toTraverseOps
import com.comcast.ip4s.IpLiteralSyntax
import db.DBService import db.DBService
import fetch.FetchService import fetch.FetchService
import parse.{Parser, WeatherData} import parse.{Parser, WeatherData}
@@ -9,14 +10,18 @@ import server.ValidateRoutes.{AggKey, CityList, DateTimeRange, ValidDate}
import io.circe.{Json, Printer} import io.circe.{Json, Printer}
import org.http4s._ import org.http4s._
import org.http4s.dsl.io._ import org.http4s.dsl.io._
import org.http4s.implicits._
import org.http4s.server.{Router, staticcontent} import org.http4s.server.{Router, staticcontent}
import org.http4s.server.blaze.BlazeServerBuilder import org.http4s.server.middleware.CORS
import org.http4s.server.middleware.CORSConfig
import org.http4s.server.staticcontent.FileService
import org.http4s.ember.server.EmberServerBuilder
import io.circe.syntax._ import io.circe.syntax._
import parse.Aggregate.AggregateValueImplicits.aggregateValueEncoder import parse.Aggregate.AggregateValueImplicits.aggregateValueEncoder
import parse.Aggregate.{AggregateKey, UserQuery} import parse.Aggregate.{AggregateKey, UserQuery}
import fs2.Stream import fs2.Stream
import org.http4s.server.middleware.CORS
import org.http4s.server.staticcontent.FileService import scala.concurrent.duration.DurationInt
object Server { object Server {
@@ -91,16 +96,26 @@ object Server {
} }
} }
val apiRoutesCors = CORS(apiRoutes) val corsConfig = CORSConfig.default
.withAnyOrigin(true)
.withAnyMethod(true)
.withAllowedMethods(Some(Set(Method.GET, Method.POST)))
.withAllowCredentials(false)
.withMaxAge(1.day)
val apiRoutesCors = CORS(apiRoutes, corsConfig)
private val httpApp = Router( private val httpApp = Router(
"/" -> staticcontent.fileService[IO](FileService.Config("./web/dist")), "/" -> staticcontent.fileService[IO](FileService.Config("./web/dist")),
"/api" -> apiRoutesCors "/api" -> apiRoutesCors
).orNotFound ).orNotFound
def run: Stream[IO, ExitCode] = def run: IO[ExitCode] =
BlazeServerBuilder[IO] EmberServerBuilder
.bindHttp(8080, "0.0.0.0") .default[IO]
.withHost(ipv4"0.0.0.0")
.withPort(port"8080")
.withHttpApp(httpApp) .withHttpApp(httpApp)
.serve .build
.useForever
} }
+1 -1
View File
@@ -1 +1 @@
VITE_API_HOST=http://localhost:8080 VITE_API_HOST=http://0.0.0.0:8080