Skip to content

Commit a02f790

Browse files
authored
Merge pull request #335 from mcanlas/use-dispatcher
Use `Dispatcher` for invoking lambda handler
2 parents 2b60acd + dc8c11a commit a02f790

5 files changed

Lines changed: 57 additions & 41 deletions

File tree

build.sbt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
* limitations under the License.
1515
*/
1616

17+
import com.typesafe.tools.mima.core._
18+
1719
name := "feral"
1820

1921
ThisBuild / tlBaseVersion := "0.2"
@@ -103,6 +105,9 @@ lazy val lambda = crossProject(JSPlatform, JVMPlatform)
103105
"org.scalameta" %%% "munit-scalacheck" % munitVersion % Test,
104106
"org.typelevel" %%% "munit-cats-effect-3" % munitCEVersion % Test,
105107
"io.circe" %%% "circe-literal" % circeVersion % Test
108+
),
109+
mimaBinaryIssueFilters ++= Seq(
110+
ProblemFilters.exclude[IncompatibleResultTypeProblem]("feral.lambda.IOLambda.setupMemo")
106111
)
107112
)
108113
.settings(commonSettings)

core/src/main/scala/feral/IOSetup.scala

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,13 @@
1616

1717
package feral
1818

19+
import scala.concurrent.Future
20+
1921
import cats.effect.unsafe.IORuntime
2022
import cats.effect.kernel.Resource
2123
import cats.effect.IO
22-
import cats.effect.kernel.Deferred
24+
import cats.effect.std.Dispatcher
25+
import cats.syntax.all._
2326

2427
private[feral] trait IOSetup {
2528

@@ -28,17 +31,11 @@ private[feral] trait IOSetup {
2831
protected type Setup
2932
protected def setup: Resource[IO, Setup] = Resource.pure(null.asInstanceOf[Setup])
3033

31-
private[feral] final lazy val setupMemo: IO[Setup] = {
32-
val deferred = Deferred.unsafe[IO, Either[Throwable, Setup]]
33-
setup
34-
.attempt
34+
private[feral] final lazy val setupMemo: Future[(Dispatcher[IO], Setup)] =
35+
(Dispatcher.parallel[IO](await = false), setup)
36+
.tupled
3537
.allocated
36-
.flatTap {
37-
case (setup, _) =>
38-
deferred.complete(setup)
39-
}
40-
.unsafeRunAndForget()(runtime)
41-
deferred.get.rethrow
42-
}
38+
.map(_._1) // drop unused finalizer
39+
.unsafeToFuture()(runtime)
4340

4441
}

lambda/js/src/main/scala/feral/lambda/IOLambdaPlatform.scala

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,15 @@ private[lambda] trait IOLambdaPlatform[Event, Result] {
3434
private lazy val handlerFn
3535
: js.Function2[js.Any, facade.Context, js.Promise[js.Any | Unit]] = {
3636
(event: js.Any, context: facade.Context) =>
37-
(for {
38-
lambda <- setupMemo
39-
event <- IO.fromEither(decodeJs[Event](event))
40-
result <- lambda(event, Context.fromJS(context))
41-
} yield result.map(_.asJsAny).orUndefined).unsafeToPromise()(runtime)
37+
setupMemo.toJSPromise(scala.concurrent.ExecutionContext.parasitic).`then`[js.Any] {
38+
case (dispatcher, lambda) =>
39+
val io =
40+
for {
41+
event <- IO.fromEither(decodeJs[Event](event))
42+
result <- lambda(event, Context.fromJS(context))
43+
} yield result.map(_.asJsAny).orUndefined
44+
45+
dispatcher.unsafeToPromise(io)
46+
}
4247
}
4348
}

lambda/jvm/src/main/scala/feral/lambda/IOLambdaPlatform.scala

Lines changed: 30 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@
1616

1717
package feral.lambda
1818

19+
import scala.concurrent.Await
20+
import scala.concurrent.duration.Duration
21+
1922
import cats.data.OptionT
2023
import cats.effect.IO
2124
import cats.effect.kernel.Resource
@@ -34,29 +37,33 @@ private[lambda] abstract class IOLambdaPlatform[Event, Result]
3437
final def handleRequest(
3538
input: InputStream,
3639
output: OutputStream,
37-
context: lambdaRuntime.Context): Unit =
38-
Resource
39-
.eval {
40-
for {
41-
lambda <- setupMemo
42-
event <- fs2
43-
.io
44-
.readInputStream(IO.pure(input), 8192, closeAfterUse = false)
45-
.through(circe.fs2.byteStreamParser)
46-
.through(circe.fs2.decoder[IO, Event])
47-
.head
48-
.compile
49-
.lastOrError
50-
context <- IO(Context.fromJava[IO](context))
51-
_ <- OptionT(lambda(event, context)).foreachF { result =>
52-
Resource.fromAutoCloseable(IO(new OutputStreamWriter(output))).use { writer =>
53-
IO.blocking(Printer.noSpaces.unsafePrintToAppendable(result.asJson, writer))
40+
context: lambdaRuntime.Context): Unit = {
41+
val (dispatcher, lambda) =
42+
Await.result(setupMemo, Duration.Inf)
43+
44+
dispatcher.unsafeRunSync {
45+
Resource
46+
.eval {
47+
for {
48+
event <- fs2
49+
.io
50+
.readInputStream(IO.pure(input), 8192, closeAfterUse = false)
51+
.through(circe.fs2.byteStreamParser)
52+
.through(circe.fs2.decoder[IO, Event])
53+
.head
54+
.compile
55+
.lastOrError
56+
context <- IO(Context.fromJava[IO](context))
57+
_ <- OptionT(lambda(event, context)).foreachF { result =>
58+
Resource.fromAutoCloseable(IO(new OutputStreamWriter(output))).use { writer =>
59+
IO.blocking(Printer.noSpaces.unsafePrintToAppendable(result.asJson, writer))
60+
}
5461
}
55-
}
56-
} yield ()
57-
}
58-
.onFinalize(IO.blocking(input.close()) &> IO.blocking(output.close()))
59-
.use_
60-
.unsafeRunSync()(runtime)
62+
} yield ()
63+
}
64+
.onFinalize(IO.blocking(input.close()) &> IO.blocking(output.close()))
65+
.use_
66+
}
67+
}
6168

6269
}

lambda/shared/src/test/scala/feral/lambda/IOLambdaSuite.scala

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,9 @@ class IOLambdaSuite extends CatsEffectSuite {
3434
.as(_.event.map(Some(_)) <* invokeCounter.getAndUpdate(_ + 1))
3535
}
3636
}
37-
handler <- lambda.setupMemo
37+
38+
handler <- IO.fromFuture(IO(lambda.setupMemo)).map(_._2)
39+
3840
_ <- ('0' to 'z')
3941
.map(_.toString)
4042
.toList

0 commit comments

Comments
 (0)