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
Run two tasks concurrently, creating a race between them and returns a pair containing both the winner's successful value and the loser represented as a still-unfinished fiber.
Run two tasks concurrently, creating a race between them and returns a pair containing both the winner's successful value and the loser represented as a still-unfinished fiber.
If the first task completes in error, then the result will complete in error, the other task being canceled.
On usage the user has the option of canceling the losing task, this being equivalent with plain race:
val ioA: IO[A] = ??? val ioB: IO[B] = ??? Concurrent[IO].racePair(ioA, ioB).flatMap { case Left((a, fiberB)) => fiberB.cancel.map(_ => a) case Right((fiberA, b)) => fiberA.cancel.map(_ => b) }
See race for a simpler version that cancels the loser immediately.
Evaluates F[_]
, with the effect of starting the run-loop
being suspended in the SyncIO
context.
Evaluates F[_]
, with the effect of starting the run-loop
being suspended in the SyncIO
context.
val io = F.runAsync(fa)(cb) // Running io results in evaluation of `fa` starting io.unsafeRunSync
Evaluates F[_]
with the ability to cancel it.
Evaluates F[_]
with the ability to cancel it.
The returned SyncIO[CancelToken[F]]
is a suspended cancelable
action that can be used to cancel the running computation.
CancelToken is nothing more than an alias for F[Unit]
and needs to be evaluated in order for cancelation of the
active process to occur.
Contract:
Start concurrent execution of the source suspended in
the F
context.
Start concurrent execution of the source suspended in
the F
context.
Returns a Fiber that can be used to either join or cancel the running computation, being similar in spirit (but not in implementation) to starting a thread.
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
Creates a cancelable F[A]
instance that executes an
asynchronous process on evaluation.
Creates a cancelable F[A]
instance that executes an
asynchronous process on evaluation.
This builder accepts a registration function that is being injected with a side-effectful callback, to be called when the asynchronous process is complete with a final result.
The registration function is also supposed to return
a CancelToken, which is nothing more than an
alias for F[Unit]
, capturing the logic necessary for
canceling the asynchronous process for as long as it
is still active.
Example:
import java.util.concurrent.ScheduledExecutorService import scala.concurrent.duration._ def sleep[F[_]](d: FiniteDuration) (implicit F: Concurrent[F], ec: ScheduledExecutorService): F[Unit] = { F.cancelable { cb => // Schedules task to run after delay val run = new Runnable { def run() = cb(Right(())) } val future = ec.schedule(run, d.length, d.unit) // Cancellation logic, suspended in F F.delay(future.cancel(true)) } }
Alias for suspend
that suspends the evaluation of
an F
reference and implements cats.Defer
typeclass.
Alias for suspend
that suspends the evaluation of
an F
reference and implements cats.Defer
typeclass.
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 Concurrent
type class.
Inherited from LiftIO, defines a conversion from IO
in terms of the Concurrent
type class.
N.B. expressing this conversion in terms of Concurrent
and
its capabilities means that the resulting F
is cancelable in
case the source IO
is.
To access this implementation as a standalone function, you can use Concurrent.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(_ => ())
Run two tasks concurrently and return the first to finish, either in success or error.
Run two tasks concurrently and return the first to finish, either in success or error. The loser of the race is canceled.
The two tasks are potentially executed in parallel, the winner being the first that signals a result.
As an example see Concurrent.timeoutTo
Also see racePair for a version that does not cancel the loser automatically on successful results.
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.
Type class describing effect data types that are cancelable.
In addition to the algebras of Concurrent and of Effect, instances must also implement a runCancelable operation that triggers the evaluation, suspended in the
IO
context, but that also returns a token that can be used for canceling the running computation.Note this is the safe and generic version of IO.unsafeRunCancelable.