Creates a simple, non-cancelable F[A]
instance that
executes an asynchronous process on evaluation.
Creates a simple, non-cancelable F[A]
instance that
executes an asynchronous process on evaluation.
The given function is being injected with a side-effectful callback for signaling the final result of an asynchronous process.
This operation could be derived from asyncF, because:
F.async(k) <-> F.asyncF(cb => F.delay(k(cb)))
As an example of wrapping an impure async API, here's the implementation of Async.shift:
def shift[F[_]](ec: ExecutionContext)(implicit F: Async[F]): F[Unit] = F.async { cb => // Scheduling an async boundary (logical thread fork) ec.execute(new Runnable { def run(): Unit = { // Signaling successful completion cb(Right(())) } }) }
is a function that should be called with a callback for signaling the result once it is ready
Creates a simple, non-cancelable F[A]
instance that
executes an asynchronous process on evaluation.
Creates a simple, non-cancelable F[A]
instance that
executes an asynchronous process on evaluation.
The given function is being injected with a side-effectful
callback for signaling the final result of an asynchronous
process. And its returned result needs to be a pure F[Unit]
that gets evaluated by the runtime.
Note the simpler async variant async can be derived like this:
F.async(k) <-> F.asyncF(cb => F.delay(k(cb)))
For wrapping impure APIs usually you can use the simpler async,
however asyncF
is useful in cases where impure APIs are
wrapped with the help of pure abstractions, such as
Ref.
For example here's how a simple, "pure Promise" implementation
could be implemented via Ref
(sample is for didactic purposes,
as you have a far better
Deferred available):
import cats.effect.concurrent.Ref type Callback[-A] = Either[Throwable, A] => Unit class PurePromise[F[_], A](ref: Ref[F, Either[List[Callback[A]], A]]) (implicit F: Async[F]) { def get: F[A] = F.asyncF { cb => ref.modify { case current @ Right(result) => (current, F.delay(cb(Right(result)))) case Left(list) => (Left(cb :: list), F.unit) } } def complete(value: A): F[Unit] = F.flatten(ref.modify { case Left(list) => (Right(value), F.delay(list.foreach(_(Right(value))))) case right => (right, F.unit) }) }
N.B. if F[_]
is a cancelable data type (i.e. implementing
Concurrent), then the returned F[Unit]
can be cancelable,
its evaluation hooking into the underlying cancelation mechanism
of F[_]
, so something like this behaves like you'd expect:
def delayed[F[_], A](thunk: => A) (implicit F: Async[F], timer: Timer[F]): F[A] = { timer.sleep(1.second) *> F.delay(cb( try cb(Right(thunk)) catch { case NonFatal(e) => Left(cb(Left(e))) } )) }
The asyncF
operation behaves like Sync.suspend, except
that the result has to be signaled via the provided callback.
As a matter of contract the returned F[Unit]
should not
throw errors. If it does, then the behavior is undefined.
This is because by contract the provided callback should
only be called once. Calling it concurrently, multiple times,
is a contract violation. And if the returned F[Unit]
throws,
then the implementation might have called it already, so it
would be a contract violation to call it without expensive
synchronization.
In case errors are thrown the behavior is implementation specific. The error might get logged to stderr, or via other mechanisms that are implementations specific.
is a function that should be called with a callback for signaling the result once it is ready
A generalized version of bracket which uses ExitCase to distinguish between different exit cases when releasing the acquired resource.
A generalized version of bracket which uses ExitCase to distinguish between different exit cases when releasing the acquired resource.
is an action that "acquires" some expensive resource, that needs to be used and then discarded
is the action that uses the newly allocated resource and that will provide the final result
is the action that's supposed to release the
allocated resource after use
is done, by observing
and acting on its exit condition
Evaluates F[_]
, with the effect of starting the run-loop
being suspended in the IO
context.
Evaluates F[_]
, with the effect of starting the run-loop
being suspended in the IO
context.
Note that evaluating the returned IO[Unit]
is guaranteed
to execute immediately:
val io = F.runAsync(fa)(cb) // For triggering actual execution, guaranteed to be // immediate because it doesn't wait for the result io.unsafeRunSync
Returns an IO
which runs fa
until it reaches an asynchronous
boundary.
Returns an IO
which runs fa
until it reaches an asynchronous
boundary.
If it is possible to run the entirety of fa
synchronously, its
result is returned wrapped in a Right
. Otherwise, the
continuation (asynchronous) effect is returned in a Left
.
Note that evaluating the returned IO
is guaranteed
to execute immediately.
Suspends the evaluation of an F
reference.
Suspends the evaluation of an F
reference.
Equivalent to FlatMap.flatten
for pure expressions,
the purpose of this function is to suspend side effects
in F
.
Operation meant for specifying tasks with safe resource acquisition and release in the face of errors and interruption.
Operation meant for specifying tasks with safe resource acquisition and release in the face of errors and interruption.
This operation provides the equivalent of try/catch/finally
statements in mainstream imperative languages for resource
acquisition and release.
is an action that "acquires" some expensive resource, that needs to be used and then discarded
is the action that uses the newly allocated resource and that will provide the final result
is the action that's supposed to release the
allocated resource after use
is done, irregardless of
its exit condition
Lifts any by-name parameter into the F
context.
Lifts any by-name parameter into the F
context.
Equivalent to Applicative.pure
for pure expressions,
the purpose of this function is to suspend side effects
in F
.
Executes the given finalizer
when the source is finished,
either in success or in error, or if canceled.
Executes the given finalizer
when the source is finished,
either in success or in error, or if canceled.
This variant of guaranteeCase evaluates the given finalizer
regardless of how the source gets terminated:
This equivalence always holds:
F.guarantee(fa)(f) <-> F.bracket(F.unit)(_ => fa)(_ => f)
As best practice, it's not a good idea to release resources
via guaranteeCase
in polymorphic code. Prefer bracket
for the acquisition and release of resources.
bracket for the more general operation
guaranteeCase for the version that can discriminate between termination conditions
Executes the given finalizer
when the source is finished,
either in success or in error, or if canceled, allowing
for differentiating between exit conditions.
Executes the given finalizer
when the source is finished,
either in success or in error, or if canceled, allowing
for differentiating between exit conditions.
This variant of guarantee injects an ExitCase in the provided function, allowing one to make a difference between:
This equivalence always holds:
F.guaranteeCase(fa)(f) <-> F.bracketCase(F.unit)(_ => fa)((_, e) => f(e))
As best practice, it's not a good idea to release resources
via guaranteeCase
in polymorphic code. Prefer bracketCase
for the acquisition and release of resources.
bracketCase for the more general operation
guarantee for the simpler version
Inherited from LiftIO, defines a conversion from IO
in terms of the Async
type class.
Inherited from LiftIO, defines a conversion from IO
in terms of the Async
type class.
N.B. expressing this conversion in terms of Async
and its
capabilities means that the resulting F
is not cancelable.
Concurrent then overrides this with an implementation
that is.
To access this implementation as a standalone function, you can use Async.liftIO (on the object companion).
Returns a non-terminating F[_]
, that never completes
with a result, being equivalent to async(_ => ())
Returns a non-terminating F[_]
, that never completes
with a result, being equivalent to async(_ => ())
Convert to an IO[A].
Convert to an IO[A].
The law is that toIO(liftIO(ioa)) is the same as ioa
Operation meant for ensuring a given task continues execution even when interrupted.
Operation meant for ensuring a given task continues execution even when interrupted.
(Since version 1.0.0-RC2) Use *> or productR instead.
(Since version 1.0.0-RC2) Use productREval instead.
(Since version 1.0.0-RC2) Use <* or productL instead.
(Since version 1.0.0-RC2) Use productLEval instead.
A monad that can suspend side effects into the
F
context and that supports lazy and potentially asynchronous evaluation.This type class is describing data types that:
Note this is the safe and generic version of IO.unsafeRunAsync (aka Haskell's
unsafePerformIO
).