As a little ZIO 2 example with Scala 3, here’s some code that starts to show how to use ZIO.timeout
along with ZIO.attempt
while accessing an internet URL with Scala’s Source.fromURL
.
Basically all I’m doing is:
- I attempt to access a URL using Scala’s
Source.fromURL
, - and then I add a timeout to that, specifically a
ZIO##timeout
Here’s the code:
//> using scala "3"
//> using lib "dev.zio::zio::2.1.0"
package zio_http_timeout
import zio.*
import zio.Console.*
import scala.io.Source
object ZioHttpTimeout extends ZIOAppDefault:
val blueprint: ZIO[Any, Throwable, Option[String]] =
ZIO.attempt {
Source.fromURL("http://httpbin.org/get")
.mkString
}.timeout(5.milliseconds)
/**
* NOTE: `timeout` doesn’t make this an error, it’s still
* a `success` here, but it’s value is `None`.
*/
val run = blueprint.foldZIO(
failure => printLineError(s"FAILURE = $failure"),
success => printLine( s"SUCCESS = $success")
)
As shown in the comments, the way this works is:
- If the URL is properly accessed and downloaded within the timeout setting, the
success
value is printed. This will be the text you download from the URL. Note that it is wrapped inside aSome
. - If the
ZIO.timeout
is triggered, thesuccess
value is still returned, and the result of it is aNone
. - If something is wrong with your URL, you’ll get different types of exceptions inside the
failure
value, includingjava.net.UnknownHostException
,java.net.URISyntaxException
, and possibly more.
More on ZIO.timeout
So a key here is starting to know how to work with the return value from ZIO.timeout
. Here’s what the ZIO Scaladoc says about its timeout
method:
Returns an effect that will timeout this effect, returning
None
if the timeout elapses before the effect has produced a value; and returningSome
of the produced value otherwise.If the timeout elapses without producing a value, the running effect will be safely interrupted.
WARNING: The effect returned by this method will not itself return until the underlying effect is actually interrupted. This leads to more predictable resource utilization. If early return is desired, then instead of using
effect.timeout(d)
, useeffect.disconnect.timeout(d)
, which first disconnects the effect's interruption signal before performing the timeout, resulting in earliest possible return, before an underlying effect has been successfully interrupted.
That’s helpful, because it explains the Some
and None
usage, and also talks about how to interrupt/disconnect the underlying effect.
this post is sponsored by my books: | |||
#1 New Release |
FP Best Seller |
Learn Scala 3 |
Learn FP Fast |