diff --git a/akka-actor-tests/src/test/scala/akka/actor/ActorSystemSpec.scala b/akka-actor-tests/src/test/scala/akka/actor/ActorSystemSpec.scala index ea8ce4c7d0..5a5a377efc 100644 --- a/akka-actor-tests/src/test/scala/akka/actor/ActorSystemSpec.scala +++ b/akka-actor-tests/src/test/scala/akka/actor/ActorSystemSpec.scala @@ -74,6 +74,14 @@ class ActorSystemSpec extends AkkaSpec("""akka.extensions = ["akka.actor.TestExt callbackWasRun must be(true) } + "return isTerminated status correctly" in { + val system = ActorSystem() + system.isTerminated must be(false) + system.shutdown() + system.awaitTermination() + system.isTerminated must be(true) + } + "throw RejectedExecutionException when shutdown" in { val system2 = ActorSystem("AwaitTermination", AkkaSpec.testConf) system2.shutdown() diff --git a/akka-actor/src/main/scala/akka/actor/ActorSystem.scala b/akka-actor/src/main/scala/akka/actor/ActorSystem.scala index 6cdcf8817d..63bb2caa54 100644 --- a/akka-actor/src/main/scala/akka/actor/ActorSystem.scala +++ b/akka-actor/src/main/scala/akka/actor/ActorSystem.scala @@ -182,12 +182,12 @@ abstract class ActorSystem extends ActorRefFactory { /** * Start-up time in milliseconds since the epoch. */ - val startTime = System.currentTimeMillis + val startTime: Long = System.currentTimeMillis /** * Up-time of this actor system in seconds. */ - def uptime = (System.currentTimeMillis - startTime) / 1000 + def uptime: Long = (System.currentTimeMillis - startTime) / 1000 /** * Main event bus of this actor system, used for example for logging. @@ -253,6 +253,8 @@ abstract class ActorSystem extends ActorRefFactory { * Block current thread until the system has been shutdown, or the specified * timeout has elapsed. This will block until after all on termination * callbacks have been run. + * + * @throws TimeoutException in case of timeout */ def awaitTermination(timeout: Duration): Unit @@ -270,6 +272,15 @@ abstract class ActorSystem extends ActorRefFactory { */ def shutdown(): Unit + /** + * Query the termination status: if it returns true, all callbacks have run + * and the ActorSystem has been fully stopped, i.e. + * `awaitTermination(0 seconds)` would return normally. If this method + * returns `false`, the status is actually unknown, since it might have + * changed since you queried it. + */ + def isTerminated: Boolean + /** * Registers the provided extension and creates its payload, if this extension isn't already registered * This method has putIfAbsent-semantics, this method can potentially block, waiting for the initialization @@ -499,6 +510,7 @@ class ActorSystemImpl protected[akka] (val name: String, applicationConfig: Conf def registerOnTermination(code: Runnable) { terminationCallbacks.add(code) } def awaitTermination(timeout: Duration) { Await.ready(terminationCallbacks, timeout) } def awaitTermination() = awaitTermination(Duration.Inf) + def isTerminated = terminationCallbacks.isTerminated def shutdown(): Unit = guardian.stop() @@ -634,5 +646,7 @@ class ActorSystemImpl protected[akka] (val name: String, applicationConfig: Conf } final def result(atMost: Duration)(implicit permit: CanAwait): Unit = ready(atMost) + + final def isTerminated: Boolean = latch.getCount == 0 } }