Skip to content

Instantly share code, notes, and snippets.

@samspills
Last active January 16, 2023 21:40
Show Gist options
  • Select an option

  • Save samspills/5a59db10a7d1b7b349fafae14cf42c3a to your computer and use it in GitHub Desktop.

Select an option

Save samspills/5a59db10a7d1b7b349fafae14cf42c3a to your computer and use it in GitHub Desktop.
toy example of an http server to query or update a ref, which is also being updated on a schedule
//> using lib "co.fs2::fs2-core:3.4.0"
//> using lib "org.typelevel::cats-effect:3.4.4"
//
//> using lib "org.http4s::http4s-core:0.23.17"
//> using lib "org.http4s::http4s-dsl:0.23.17"
//> using lib "org.http4s::http4s-ember-server:0.23.17"
//> using lib "org.http4s::http4s-server:0.23.17"
import fs2.Stream
import cats.effect.IO
import cats.effect.IOApp
import scala.concurrent.duration._
import cats.effect.kernel.Ref
import org.http4s.HttpRoutes
import org.http4s.dsl.io._
import org.http4s.implicits._
import org.http4s.server.Router
import org.http4s.ember.server.EmberServerBuilder
import com.comcast.ip4s._
import cats.effect.ExitCode
import cats.effect.kernel.Resource
import org.http4s.server.Server
object ScheduledEndpoint extends IOApp {
def refService(ref: Ref[IO, Int]) = HttpRoutes.of[IO] {
case GET -> Root / "ref" =>
for {
i <- ref.get
resp <- Ok(s"Current ref value is: $i")
} yield resp
case PUT -> Root / "ref" / IntVar(value) =>
for {
_ <- ref.set(value)
resp <- Ok(s"Updated the ref value to: $value")
} yield resp
}
def scheduledUpdater(ref: Ref[IO, Int]): Resource[IO, Unit] = {
val prog = ref
.updateAndGet(i => i + 1)
.flatMap(i => IO.println(s"scheduled update: added 1, ref value is now $i"))
Stream.repeatEval(prog).metered(1.minute).compile.resource.drain
}
def run(args: List[String]): IO[ExitCode] = {
val serverAndUpdater: Resource[IO, (Server, Unit)] = for {
ref <- Resource.eval(Ref[IO].of(1))
httpApp = Router("/" -> refService(ref)).orNotFound
updater = scheduledUpdater(ref)
server = EmberServerBuilder
.default[IO]
.withHost(ipv4"0.0.0.0")
.withPort(port"8080")
.withHttpApp(httpApp)
.build
serverAndUpdater <- Resource.both(server, updater)
} yield serverAndUpdater
serverAndUpdater.useForever.as(ExitCode.Success)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment