final class TaskLocal[A] extends AnyRef
A TaskLocal
is like a
ThreadLocal
that is pure and with a flexible scope, being processed in the
context of the Task data type.
This data type wraps monix.execution.misc.Local.
Just like a ThreadLocal
, usage of a TaskLocal
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 Task.Options.localContextPropagation
set to true
.
One way to achieve this is with Task.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 Task.runToFutureOpt or
Task.runToFutureOpt instead of runAsync
and specify the set of
options implicitly:
{ implicit val options = Task.defaultOptions.enableLocalContextPropagation // Options passed implicitly val f = t.runToFutureOpt }
Full example:
import monix.eval.{Task, TaskLocal} val task: Task[Unit] = for { local <- TaskLocal(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 = Task.defaultOptions.enableLocalContextPropagation // Triggering actual execution val result = task.runToFutureOpt
- Source
- TaskLocal.scala
- Alphabetic
- By Inheritance
- TaskLocal
- 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[R](value: A)(task: Task[R]): Task[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: Task[Int] = for { local <- TaskLocal(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 Task 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[R](task: Task[R]): Task[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: Task[Int] = for { local <- TaskLocal(0) value <- local.bindClear(local.read.map(_ * 2)) } yield value
- def bindL[R](value: Task[A])(task: Task[R]): Task[R]
Binds the local var to a
value
for the duration of the giventask
execution, thevalue
itself being lazily evaluated in the Task context.Binds the local var to a
value
for the duration of the giventask
execution, thevalue
itself being lazily evaluated in the Task context.// Should yield 200 on execution, regardless of what value // we have in `local` at the time of evaluation val task: Task[Int] = for { local <- TaskLocal(0) value <- local.bindL(Task.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 Task 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: Task[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() @HotSpotIntrinsicCandidate()
- final def eq(arg0: AnyRef): Boolean
- Definition Classes
- AnyRef
- def equals(arg0: AnyRef): Boolean
- Definition Classes
- AnyRef → Any
- final def getClass(): Class[_ <: AnyRef]
- Definition Classes
- AnyRef → Any
- Annotations
- @native() @HotSpotIntrinsicCandidate()
- def hashCode(): Int
- Definition Classes
- AnyRef → Any
- Annotations
- @native() @HotSpotIntrinsicCandidate()
- final def isInstanceOf[T0]: Boolean
- Definition Classes
- Any
- def local: Task[Local[A]]
Returns monix.execution.misc.Local instance used in this TaskLocal.
Returns monix.execution.misc.Local instance used in this TaskLocal.
Note that
TaskLocal.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() @HotSpotIntrinsicCandidate()
- final def notifyAll(): Unit
- Definition Classes
- AnyRef
- Annotations
- @native() @HotSpotIntrinsicCandidate()
- def read: Task[A]
Returns the current local value (in the
Task
context). - final def synchronized[T0](arg0: => T0): T0
- Definition Classes
- AnyRef
- def toString(): String
- Definition Classes
- AnyRef → Any
- 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()
- final def wait(): Unit
- Definition Classes
- AnyRef
- Annotations
- @throws(classOf[java.lang.InterruptedException])
- def write(value: A): Task[Unit]
Updates the local value.
This is the API documentation for the Monix library.
Package Overview
monix.execution exposes lower level primitives for dealing with asynchronous execution:
Atomic
types, as alternative tojava.util.concurrent.atomic
monix.catnap exposes pure abstractions built on top of the Cats-Effect type classes:
monix.eval is for dealing with evaluation of results, thus exposing Task and Coeval.
monix.reactive exposes the
Observable
pattern:Observable
implementationsmonix.tail exposes Iterant for purely functional pull based streaming:
Batch
andBatchCursor
, the alternatives to Scala'sIterable
andIterator
respectively that we are using within Iterant's encodingYou can control evaluation with type you choose - be it Task, Coeval, cats.effect.IO or your own as long as you provide correct cats-effect or cats typeclass instance.