Packages

trait TimeLimits extends AnyRef

Trait that provides failAfter and cancelAfter methods, which allow you to specify a time limit for an operation passed as a by-name parameter, as well as a way to signal it if the operation exceeds its time limit.

The time limit is passed as the first parameter, as a Span. The operation is passed as the second parameter. A Signaler, a strategy for interrupting the operation, is passed as an implicit third parameter. Here's a simple example of its use:

failAfter(Span(100, Millis)) {
  Thread.sleep(200)
}

The above code will eventually produce a TestFailedDueToTimeoutException with a message that indicates a time limit has been exceeded:

The code passed to failAfter did not complete within 100 milliseconds.

If you use cancelAfter in place of failAfter, a TestCanceledException will be thrown instead, also with a message that indicates a time limit has been exceeded:

The code passed to cancelAfter did not complete within 100 milliseconds.

If you prefer you can mix in or import the members of SpanSugar and place a units value after the integer timeout. Here are some examples:

import org.scalatest.time.SpanSugar._

failAfter(100 millis) { Thread.sleep(200) }
failAfter(1 second) { Thread.sleep(2000) }

The code passed via the by-name parameter to failAfter or cancelAfter will be executed by the thread that invoked failAfter or cancelAfter, so that no synchronization is necessary to access variables declared outside the by-name.

var result = -1 // No need to make this volatile
failAfter(100 millis) {
  result = accessNetService()
}
result should be (99)

The failAfter or cancelAfter method will create a timer that runs on a different thread than the thread that invoked failAfter or cancelAfter, so that it can detect when the time limit has been exceeded and attempt to signal the main thread. Because different operations can require different signaling strategies, the failAfter and cancelAfter methods accept an implicit third parameter of type Signaler that is responsible for signaling the main thread.

Configuring failAfter or cancelAfter with a Signaler

The Signaler companion object declares an implicit val of type Signaler that returns a DoNotSignal. This serves as the default signaling strategy. If you wish to use a different strategy, you can declare an implicit val that establishes a different Signaler as the policy. Here's an example in which the default signaling strategy is changed to ThreadSignaler, which does not attempt to interrupt the main thread in any way:

override val signaler: Signaler = ThreadSignaler
failAfter(100 millis) {
  Thread.sleep(500)
}

As with the default Signaler, the above code will eventually produce a TestFailedDueToTimeoutException with a message that indicates a timeout expired. However, instead of throwing the exception after approximately 500 milliseconds, it will throw it after approximately 100 milliseconds.

This illustrates an important feature of failAfter and cancelAfter: it will throw a TestFailedDueToTimeoutException (or TestCanceledException in case of cancelAfter) if the code passed as the by-name parameter takes longer than the specified timeout to execute, even if it is allowed to run to completion beyond the specified timeout and returns normally.

ScalaTest provides the following Signaler implementations:

Signaler implementation Usage
DoNotSignal The default signaler, does not attempt to interrupt the main test thread in any way
ThreadSignaler Invokes interrupt on the main test thread. This will set the interrupted status for the main test thread and, if the main thread is blocked, will in some cases cause the main thread to complete abruptly with an InterruptedException.
SelectorSignaler Invokes wakeup on the passed java.nio.channels.Selector, which will cause the main thread, if blocked in Selector.select, to complete abruptly with a ClosedSelectorException.
SocketSignaler Invokes close on the java.io.Socket, which will cause the main thread, if blocked in a read or write of an java.io.InputStream or java.io.OutputStream that uses the Socket, to complete abruptly with a SocketException.

You may wish to create your own Signaler in some situations. For example, if your operation is performing a loop and can check a volatile flag each pass through the loop, you could write a Signaler that sets that flag so that the next time around, the loop would exit.

Source
TimeLimits.scala
Linear Supertypes
AnyRef, Any
Ordering
  1. Alphabetic
  2. By Inheritance
Inherited
  1. TimeLimits
  2. AnyRef
  3. Any
  1. Hide All
  2. Show All
Visibility
  1. Public
  2. Protected

Value Members

  1. final def !=(arg0: Any): Boolean
    Definition Classes
    AnyRef → Any
  2. final def ##: Int
    Definition Classes
    AnyRef → Any
  3. final def ==(arg0: Any): Boolean
    Definition Classes
    AnyRef → Any
  4. final def asInstanceOf[T0]: T0
    Definition Classes
    Any
  5. def cancelAfter[T](timeout: Span)(fun: => T)(implicit signaler: Signaler, prettifier: Prettifier = implicitly[Prettifier], pos: Position = implicitly[source.Position], timed: Timed[T] = implicitly[Timed[T]]): T

    Executes the passed function, enforcing the passed time limit by attempting to signal the operation if the time limit is exceeded, and "canceling" if the time limit has been exceeded after the function completes, where what it means to "cancel" is determined by the implicitly passed Timed[T] instance.

    Executes the passed function, enforcing the passed time limit by attempting to signal the operation if the time limit is exceeded, and "canceling" if the time limit has been exceeded after the function completes, where what it means to "cancel" is determined by the implicitly passed Timed[T] instance.

    The Timed companion object offers three implicits, one for FutureOutcome, one for Future[U] and one for any other type. The implicit Timed[FutureOutcome] defines cancelation as canceling the FutureOutcome: no exception will be thrown. The implicit Timed[Future[U]] defines canceling as failing the Future[U] with a TestCanceledException: no exception will be thrown. The implicit for any other type defines failure as throwing TestCanceledException. For the details, see the Scaladoc of the implicit Timed providers in the Timed companion object.

    timeout

    the maximimum amount of time allowed for the passed operation

    signaler

    a strategy for signaling the passed operation

    prettifier

    a Prettifier for prettifying error messages

    pos

    the Position of the caller site

    timed

    the Timed type class that provides the behavior implementation of the timing restriction.

  6. def clone(): AnyRef
    Attributes
    protected[lang]
    Definition Classes
    AnyRef
    Annotations
    @throws(classOf[java.lang.CloneNotSupportedException]) @native()
  7. final def eq(arg0: AnyRef): Boolean
    Definition Classes
    AnyRef
  8. def equals(arg0: AnyRef): Boolean
    Definition Classes
    AnyRef → Any
  9. def failAfter[T](timeout: Span)(fun: => T)(implicit signaler: Signaler, prettifier: Prettifier = implicitly[Prettifier], pos: Position = implicitly[source.Position], timed: Timed[T] = implicitly[Timed[T]]): T

    Executes the passed function, enforcing the passed time limit by attempting to signal the operation if the time limit is exceeded, and "failing" if the time limit has been exceeded after the function completes, where what it means to "fail" is determined by the implicitly passed Timed[T] instance.

    Executes the passed function, enforcing the passed time limit by attempting to signal the operation if the time limit is exceeded, and "failing" if the time limit has been exceeded after the function completes, where what it means to "fail" is determined by the implicitly passed Timed[T] instance.

    The Timed companion object offers three implicits, one for FutureOutcome, one for Future[U] and one for any other type. The implicit Timed[FutureOutcome] defines failure as failing the FutureOutcome with a TestFailedDueToTimeoutException: no exception will be thrown. The implicit Timed[Future[U]] defines failure as failing the Future[U] with a TestFailedDueToTimeoutException: no exception will be thrown. The implicit for any other type defines failure as throwing TestFailedDueToTimeoutException. For the details, see the Scaladoc of the implicit Timed providers in the Timed companion object.

    timeout

    the maximimum amount of time allowed for the passed operation

    fun

    the operation on which to enforce the passed timeout

    signaler

    a strategy for signaling the passed operation

    prettifier

    a Prettifier for prettifying error messages

    pos

    the Position of the caller site

    timed

    the Timed type class that provides the behavior implementation of the timing restriction.

  10. def finalize(): Unit
    Attributes
    protected[lang]
    Definition Classes
    AnyRef
    Annotations
    @throws(classOf[java.lang.Throwable])
  11. final def getClass(): Class[_ <: AnyRef]
    Definition Classes
    AnyRef → Any
    Annotations
    @native()
  12. def hashCode(): Int
    Definition Classes
    AnyRef → Any
    Annotations
    @native()
  13. final def isInstanceOf[T0]: Boolean
    Definition Classes
    Any
  14. final def ne(arg0: AnyRef): Boolean
    Definition Classes
    AnyRef
  15. final def notify(): Unit
    Definition Classes
    AnyRef
    Annotations
    @native()
  16. final def notifyAll(): Unit
    Definition Classes
    AnyRef
    Annotations
    @native()
  17. final def synchronized[T0](arg0: => T0): T0
    Definition Classes
    AnyRef
  18. def toString(): String
    Definition Classes
    AnyRef → Any
  19. final def wait(): Unit
    Definition Classes
    AnyRef
    Annotations
    @throws(classOf[java.lang.InterruptedException])
  20. final def wait(arg0: Long, arg1: Int): Unit
    Definition Classes
    AnyRef
    Annotations
    @throws(classOf[java.lang.InterruptedException])
  21. final def wait(arg0: Long): Unit
    Definition Classes
    AnyRef
    Annotations
    @throws(classOf[java.lang.InterruptedException]) @native()

Inherited from AnyRef

Inherited from Any

Ungrouped