I try to run function written on Scala with Cats IO using. Simple Scala functions from https://aws.amazon.com/blogs/compute/writing-aws-lambda-functions-in-scala/ and https://rockthejvm.com/articles/deploy-a-scala-application-to-aws-lambda examples works fine. But when I try run function using Cats Effect IO like this:
def execute: IO[Unit] = {
for {
task1 <- IO.pure(println("task 1"))
task2 <- IO.pure(println("task 2"))
task3 <- IO.pure(println("task 3"))
} yield ()
}
Only first task executes and function finishes. This is lambda log:
INIT_START Runtime Version: java:17.v42 Runtime Version ARN:arn:aws:lambda:eu-central-1::runtime:07e1a019fe488fb718021df9129caf01fd13d22d401104a151e929a91a82af7b
START RequestId:b032972f-4c47-4c9d-be22-c83141360bd7 Version: $LATEST
task 1
END RequestId: b032972f-4c47-4c9d-be22-c83141360bd7
REPORT RequestId: b032972f-4c47-4c9d-be22-c83141360bd7 Duration: 2211.47 ms Billed Duration: 2212 ms Memory Size: 512 MB Max Memory Used: 119 MB Init Duration: 577.36 ms
Looks like multithreading problem: task execution starts in parallel thread and program not waits while thread finishes. But yield() construction should sign that program should wait until all tasks finishes. And I not met any mentions that AWS Lambda have problems with multithreading, and IO really not run threads. What may be wrong?
Thanks to @LuisMiguelMejíaSuárez response solution was found. I created but not run IO. Working code sample below:
def task: IO[Int] = {
println("task 1")
IO.pure(1)
}
def task2(i: Int): IO[Int] = {
println(s"task 2: $i")
IO.pure(i + 1)
}
def task3(i: Int): IO[Int] = {
println(s"task 3: $i")
IO.pure(i + 1)
}
def execute: Unit = {
val mainIO = for {
task1 <- task
task2 <- task2(task1)
_ <- task3(task2)
} yield ()
mainIO.handleError(ex => logger.error(ex.getMessage))
.unsafeRunSync()
}