final class IOLocal[A] extends AnyRef
A IOLocal
is like a
ThreadLocal
that is pure and with a flexible scope, being processed in the
context of the IO data type.
This data type wraps monix.execution.misc.Local.
Just like a ThreadLocal
, usage of a IOLocal
is safe,
the state of all current locals being transported over
async boundaries (aka when threads get forked) by the Task
run-loop implementation, but only when the Task
reference
gets executed with IO.Options.localContextPropagation
set to true
, or it uses a monix.execution.schedulers.TracingScheduler.
One way to achieve this is with IO.executeWithOptions,
a single call is sufficient just before runAsync
:
import monix.execution.Scheduler.Implicits.global val t = Task(42) t.executeWithOptions(_.enableLocalContextPropagation) // triggers the actual execution .runToFuture
Another possibility is to use IO.runToFutureOpt or
IO.runToFutureOpt instead of runAsync
and specify the set of
options implicitly:
{ implicit val options = IO.defaultOptions.enableLocalContextPropagation // Options passed implicitly val f = t.runToFutureOpt }
Full example:
import monix.bio.{UIO, IOLocal} val task: UIO[Unit] = for { local <- IOLocal(0) value1 <- local.read // value1 == 0 _ <- local.write(100) value2 <- local.read // value2 == 100 value3 <- local.bind(200)(local.read.map(_ * 2)) // value3 == 200 * 2 value4 <- local.read // value4 == 100 _ <- local.clear value5 <- local.read // value5 == 0 } yield { // Should print 0, 100, 400, 100, 0 println("value1: " + value1) println("value2: " + value2) println("value3: " + value3) println("value4: " + value4) println("value5: " + value5) } // For transporting locals over async boundaries defined by // Task, any Scheduler will do, however for transporting locals // over async boundaries managed by Future and others, you need // a `TracingScheduler` here: import monix.execution.Scheduler.Implicits.global // Needs enabling the "localContextPropagation" option // just before execution implicit val opts = IO.defaultOptions.enableLocalContextPropagation // Triggering actual execution val result = task.runToFutureOpt
- Source
- IOLocal.scala
- Alphabetic
- By Inheritance
- IOLocal
- AnyRef
- Any
- Hide All
- Show All
- Public
- Protected
Value Members
- final def !=(arg0: Any): Boolean
- Definition Classes
- AnyRef → Any
- final def ##: Int
- Definition Classes
- AnyRef → Any
- final def ==(arg0: Any): Boolean
- Definition Classes
- AnyRef → Any
- final def asInstanceOf[T0]: T0
- Definition Classes
- Any
- def bind[E, R](value: A)(task: IO[E, R]): IO[E, R]
Binds the local var to a
value
for the duration of the giventask
execution.Binds the local var to a
value
for the duration of the giventask
execution.// Should yield 200 on execution, regardless of what value // we have in `local` at the time of evaluation val task: UIO[Int] = for { local <- IOLocal(0) value <- local.bind(100)(local.read.map(_ * 2)) } yield value
- value
is the value to be set in this local var when the task evaluation is triggered (aka lazily)
- task
is the IO to wrap, having the given
value
as the response to read queries and transported over asynchronous boundaries — on finish the local gets reset to the previous value
- See also
bindL for the version with a lazy
value
.
- def bindClear[E, R](task: IO[E, R]): IO[E, R]
Clears the local var to the default for the duration of the given
task
execution.Clears the local var to the default for the duration of the given
task
execution.// Should yield 0 on execution, regardless of what value // we have in `local` at the time of evaluation val task: UIO[Int] = for { local <- IOLocal(0) value <- local.bindClear(local.read.map(_ * 2)) } yield value
- def bindL[E, R](value: IO[E, A])(task: IO[E, R]): IO[E, R]
Binds the local var to a
value
for the duration of the giventask
execution, thevalue
itself being lazily evaluated in the IO context.Binds the local var to a
value
for the duration of the giventask
execution, thevalue
itself being lazily evaluated in the IO context.// Should yield 200 on execution, regardless of what value // we have in `local` at the time of evaluation val task: UIO[Int] = for { local <- IOLocal(0) value <- local.bindL(UIO.eval(100))(local.read.map(_ * 2)) } yield value
- value
is the value to be set in this local var when the task evaluation is triggered (aka lazily)
- task
is the IO to wrap, having the given
value
as the response to read queries and transported over asynchronous boundaries — on finish the local gets reset to the previous value
- See also
bind for the version with a strict
value
.
- def clear: UIO[Unit]
Clears the local value, making it return its
default
. - def clone(): AnyRef
- Attributes
- protected[lang]
- Definition Classes
- AnyRef
- Annotations
- @throws(classOf[java.lang.CloneNotSupportedException]) @native()
- final def eq(arg0: AnyRef): Boolean
- Definition Classes
- AnyRef
- def equals(arg0: AnyRef): Boolean
- Definition Classes
- AnyRef → Any
- def finalize(): Unit
- Attributes
- protected[lang]
- Definition Classes
- AnyRef
- Annotations
- @throws(classOf[java.lang.Throwable])
- final def getClass(): Class[_ <: AnyRef]
- Definition Classes
- AnyRef → Any
- Annotations
- @native()
- def hashCode(): Int
- Definition Classes
- AnyRef → Any
- Annotations
- @native()
- final def isInstanceOf[T0]: Boolean
- Definition Classes
- Any
- def local: UIO[Local[A]]
Returns monix.execution.misc.Local instance used in this IOLocal.
Returns monix.execution.misc.Local instance used in this IOLocal.
Note that
IOLocal.bind
will restore the original local value on the thread where theTask's
run-loop ends up so it might lead to leaving local modified in other thread. - final def ne(arg0: AnyRef): Boolean
- Definition Classes
- AnyRef
- final def notify(): Unit
- Definition Classes
- AnyRef
- Annotations
- @native()
- final def notifyAll(): Unit
- Definition Classes
- AnyRef
- Annotations
- @native()
- def read: UIO[A]
Returns the current local value (in the
IO
context). - final def synchronized[T0](arg0: => T0): T0
- Definition Classes
- AnyRef
- def toString(): String
- Definition Classes
- AnyRef → Any
- final def wait(): Unit
- Definition Classes
- AnyRef
- Annotations
- @throws(classOf[java.lang.InterruptedException])
- final def wait(arg0: Long, arg1: Int): Unit
- Definition Classes
- AnyRef
- Annotations
- @throws(classOf[java.lang.InterruptedException])
- final def wait(arg0: Long): Unit
- Definition Classes
- AnyRef
- Annotations
- @throws(classOf[java.lang.InterruptedException]) @native()
- def write(value: A): UIO[Unit]
Updates the local value.