scala.concurrent.CanAwait
sealed trait CanAwait extends AnyRef
This marker trait is used by Await to ensure that Awaitable.ready and
Awaitable.result are not directly called by user code. An implicit instance of
this trait is only available when user code is currently calling the methods on
Await.
Annotations
@ implicitNotFound (msg =…)
Source
Full Source:
/* __ *\
** ________ ___ / / ___ Scala API **
** / __/ __// _ | / / / _ | (c) 2003-2013, LAMP/EPFL **
** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
** /____/\___/_/ |_/____/_/ | | **
** |/ **
\* */
package scala
import scala.concurrent.duration.Duration
import scala.annotation.implicitNotFound
/** This package object contains primitives for concurrent and parallel programming.
*
* == Guide ==
*
* A more detailed guide to Futures and Promises, including discussion and examples
* can be found at
* [[http://docs.scala-lang.org/overviews/core/futures.html]].
*
* == Common Imports ==
*
* When working with Futures, you will often find that importing the whole concurrent
* package is convenient, furthermore you are likely to need an implicit ExecutionContext
* in scope for many operations involving Futures and Promises:
*
* {{{
* import scala.concurrent._
* import ExecutionContext.Implicits.global
* }}}
*
* == Specifying Durations ==
*
* Operations often require a duration to be specified. A duration DSL is available
* to make defining these easier:
*
* {{{
* import scala.concurrent.duration._
* val d: Duration = 10.seconds
* }}}
*
* == Using Futures For Non-blocking Computation ==
*
* Basic use of futures is easy with the factory method on Future, which executes a
* provided function asynchronously, handing you back a future result of that function
* without blocking the current thread. In order to create the Future you will need
* either an implicit or explicit ExecutionContext to be provided:
*
* {{{
* import scala.concurrent._
* import ExecutionContext.Implicits.global // implicit execution context
*
* val firstZebra: Future[Int] = Future {
* val source = scala.io.Source.fromFile("/etc/dictionaries-common/words")
* source.toSeq.indexOfSlice("zebra")
* }
* }}}
*
* == Avoid Blocking ==
*
* Although blocking is possible in order to await results (with a mandatory timeout duration):
*
* {{{
* import scala.concurrent.duration._
* Await.result(firstZebra, 10.seconds)
* }}}
*
* and although this is sometimes necessary to do, in particular for testing purposes, blocking
* in general is discouraged when working with Futures and concurrency in order to avoid
* potential deadlocks and improve performance. Instead, use callbacks or combinators to
* remain in the future domain:
*
* {{{
* val animalRange: Future[Int] = for {
* aardvark <- firstAardvark
* zebra <- firstZebra
* } yield zebra - aardvark
*
* animalRange.onSuccess {
* case x if x > 500000 => println("It's a long way from Aardvark to Zebra")
* }
* }}}
*/
package object concurrent {
type ExecutionException = java . util . concurrent . ExecutionException
type CancellationException = java . util . concurrent . CancellationException
type TimeoutException = java . util . concurrent . TimeoutException
/** Starts an asynchronous computation and returns a `Future` object with the result of that computation.
*
* The result becomes available once the asynchronous computation is completed.
*
* @tparam T the type of the result
* @param body the asynchronous computation
* @param executor the execution context on which the future is run
* @return the `Future` holding the result of the computation
*/
@deprecated ( "Use `Future { ... }` instead." , "2.11.0" )
// removal planned for 2.13.0
def future [ T ]( body : => T )( implicit @deprecatedName ( 'execctx) executor : ExecutionContext ) : Future [ T ] = Future [ T ]( body )
/** Creates a promise object which can be completed with a value or an exception.
*
* @tparam T the type of the value in the promise
* @return the newly created `Promise` object
*/
@deprecated ( "Use `Promise[T]()` instead." , "2.11.0" )
// removal planned for 2.13.0
def promise [ T ]() : Promise [ T ] = Promise [ T ]()
/** Used to designate a piece of code which potentially blocks, allowing the current [[BlockContext]] to adjust
* the runtime's behavior.
* Properly marking blocking code may improve performance or avoid deadlocks.
*
* Blocking on an [[Awaitable]] should be done using [[Await.result]] instead of `blocking`.
*
* @param body A piece of code which contains potentially blocking or long running calls.
* @throws CancellationException if the computation was cancelled
* @throws InterruptedException in the case that a wait within the blocking `body` was interrupted
*/
@throws ( classOf [ Exception ])
def blocking [ T ]( body : => T ) : T = BlockContext . current . blockOn ( body )( scala . concurrent . AwaitPermission )
}
package concurrent {
/**
* This marker trait is used by [[Await]] to ensure that [[Awaitable.ready]] and [[Awaitable.result]]
* are not directly called by user code. An implicit instance of this trait is only available when
* user code is currently calling the methods on [[Await]].
*/
@implicitNotFound ( "Don't call `Awaitable` methods directly, use the `Await` object." )
sealed trait CanAwait
/**
* Internal usage only, implementation detail.
*/
private [ concurrent ] object AwaitPermission extends CanAwait
/**
* `Await` is what is used to ensure proper handling of blocking for `Awaitable` instances.
*
* While occasionally useful, e.g. for testing, it is recommended that you avoid Await
* when possible in favor of callbacks and combinators like onComplete and use in
* for comprehensions. Await will block the thread on which it runs, and could cause
* performance and deadlock issues.
*/
object Await {
/**
* Await the "completed" state of an `Awaitable`.
*
* Although this method is blocking, the internal use of [[scala.concurrent.blocking blocking]] ensures that
* the underlying [[ExecutionContext]] is prepared to properly manage the blocking.
*
* @param awaitable
* the `Awaitable` to be awaited
* @param atMost
* maximum wait time, which may be negative (no waiting is done),
* [[scala.concurrent.duration.Duration.Inf Duration.Inf]] for unbounded waiting, or a finite positive
* duration
* @return the `awaitable`
* @throws InterruptedException if the current thread is interrupted while waiting
* @throws TimeoutException if after waiting for the specified time this `Awaitable` is still not ready
* @throws IllegalArgumentException if `atMost` is [[scala.concurrent.duration.Duration.Undefined Duration.Undefined]]
*/
@throws ( classOf [ TimeoutException ])
@throws ( classOf [ InterruptedException ])
def ready [ T ]( awaitable : Awaitable [ T ], atMost : Duration ) : awaitable. type =
blocking ( awaitable . ready ( atMost )( AwaitPermission ))
/**
* Await and return the result (of type `T`) of an `Awaitable`.
*
* Although this method is blocking, the internal use of [[scala.concurrent.blocking blocking]] ensures that
* the underlying [[ExecutionContext]] to properly detect blocking and ensure that there are no deadlocks.
*
* @param awaitable
* the `Awaitable` to be awaited
* @param atMost
* maximum wait time, which may be negative (no waiting is done),
* [[scala.concurrent.duration.Duration.Inf Duration.Inf]] for unbounded waiting, or a finite positive
* duration
* @return the result value if `awaitable` is completed within the specific maximum wait time
* @throws InterruptedException if the current thread is interrupted while waiting
* @throws TimeoutException if after waiting for the specified time `awaitable` is still not ready
* @throws IllegalArgumentException if `atMost` is [[scala.concurrent.duration.Duration.Undefined Duration.Undefined]]
*/
@throws ( classOf [ Exception ])
def result [ T ]( awaitable : Awaitable [ T ], atMost : Duration ) : T =
blocking ( awaitable . result ( atMost )( AwaitPermission ))
}
}