Merge branch 'master' into wip-1581-patterns-ask

This commit is contained in:
Roland 2012-01-20 19:29:17 +01:00
commit 34a0f005b1
306 changed files with 1384 additions and 731 deletions

View file

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com> * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/ */
package akka.actor; package akka.actor;

View file

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com> * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/ */
package akka.util; package akka.util;

View file

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com> * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/ */
package akka package akka

View file

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com> * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/ */
package akka.actor package akka.actor

View file

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com> * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/ */
package akka.actor package akka.actor

View file

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com> * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/ */
package akka.actor package akka.actor

View file

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com> * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/ */
package akka.actor package akka.actor

View file

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com> * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/ */
package akka.actor package akka.actor

View file

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com> * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/ */
package akka.actor package akka.actor

View file

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com> * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/ */
package akka.actor package akka.actor

View file

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com> * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/ */
package akka.actor package akka.actor

View file

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com> * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/ */
package akka.actor package akka.actor

View file

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com> * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/ */
package akka.actor package akka.actor

View file

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com> * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/ */
package akka.actor package akka.actor

View file

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com> * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/ */
package akka.actor package akka.actor

View file

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com> * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/ */
package akka.actor package akka.actor
@ -14,7 +14,7 @@ object LocalActorRefProviderSpec {
akka { akka {
actor { actor {
default-dispatcher { default-dispatcher {
core-pool-size-min = 8 core-pool-size-min = 16
core-pool-size-max = 16 core-pool-size-max = 16
} }
} }

View file

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com> * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/ */
package akka.actor package akka.actor

View file

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com> * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/ */
package akka.actor package akka.actor

View file

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com> * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/ */
package akka.actor package akka.actor

View file

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com> * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/ */
package akka.actor package akka.actor

View file

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com> * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/ */
package akka.actor package akka.actor

View file

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com> * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/ */
package akka.actor package akka.actor

View file

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com> * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/ */
package akka.actor package akka.actor

View file

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com> * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/ */
package akka.actor package akka.actor

View file

@ -1,7 +1,7 @@
package akka.actor package akka.actor
/** /**
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com> * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/ */
import org.scalatest.{ BeforeAndAfterAll, BeforeAndAfterEach } import org.scalatest.{ BeforeAndAfterAll, BeforeAndAfterEach }

View file

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com> * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/ */
package akka.actor.dispatch package akka.actor.dispatch
@ -451,7 +451,6 @@ object DispatcherModelSpec {
private val instance: MessageDispatcher = { private val instance: MessageDispatcher = {
configureThreadPool(config, configureThreadPool(config,
threadPoolConfig new Dispatcher(prerequisites, threadPoolConfig new Dispatcher(prerequisites,
config.getString("name"),
config.getString("id"), config.getString("id"),
config.getInt("throughput"), config.getInt("throughput"),
Duration(config.getNanoseconds("throughput-deadline-time"), TimeUnit.NANOSECONDS), Duration(config.getNanoseconds("throughput-deadline-time"), TimeUnit.NANOSECONDS),
@ -526,7 +525,6 @@ object BalancingDispatcherModelSpec {
private val instance: MessageDispatcher = { private val instance: MessageDispatcher = {
configureThreadPool(config, configureThreadPool(config,
threadPoolConfig new BalancingDispatcher(prerequisites, threadPoolConfig new BalancingDispatcher(prerequisites,
config.getString("name"),
config.getString("id"), config.getString("id"),
config.getInt("throughput"), config.getInt("throughput"),
Duration(config.getNanoseconds("throughput-deadline-time"), TimeUnit.NANOSECONDS), Duration(config.getNanoseconds("throughput-deadline-time"), TimeUnit.NANOSECONDS),

View file

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com> * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/ */
package akka.actor.dispatch package akka.actor.dispatch
@ -58,11 +58,6 @@ class DispatchersSpec extends AkkaSpec(DispatchersSpec.config) {
dispatcher.throughput must be(17) dispatcher.throughput must be(17)
} }
"use specific name" in {
val dispatcher = lookup("myapp.mydispatcher")
dispatcher.name must be("mydispatcher")
}
"use specific id" in { "use specific id" in {
val dispatcher = lookup("myapp.mydispatcher") val dispatcher = lookup("myapp.mydispatcher")
dispatcher.id must be("myapp.mydispatcher") dispatcher.id must be("myapp.mydispatcher")
@ -95,7 +90,6 @@ class DispatchersSpec extends AkkaSpec(DispatchersSpec.config) {
val d1 = lookup("myapp.mydispatcher") val d1 = lookup("myapp.mydispatcher")
val d2 = lookup("myapp.mydispatcher") val d2 = lookup("myapp.mydispatcher")
d1 must be === d2 d1 must be === d2
d1.name must be("mydispatcher")
} }
} }

View file

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com> * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/ */
package akka.config package akka.config
@ -23,8 +23,9 @@ class ConfigSpec extends AkkaSpec(ConfigFactory.defaultReference) {
getString("akka.version") must equal("2.0-SNAPSHOT") getString("akka.version") must equal("2.0-SNAPSHOT")
settings.ConfigVersion must equal("2.0-SNAPSHOT") settings.ConfigVersion must equal("2.0-SNAPSHOT")
getBoolean("akka.daemonic") must equal(false)
getString("akka.actor.default-dispatcher.type") must equal("Dispatcher") getString("akka.actor.default-dispatcher.type") must equal("Dispatcher")
getString("akka.actor.default-dispatcher.name") must equal("default-dispatcher")
getMilliseconds("akka.actor.default-dispatcher.keep-alive-time") must equal(60 * 1000) getMilliseconds("akka.actor.default-dispatcher.keep-alive-time") must equal(60 * 1000)
getDouble("akka.actor.default-dispatcher.core-pool-size-factor") must equal(3.0) getDouble("akka.actor.default-dispatcher.core-pool-size-factor") must equal(3.0)
getDouble("akka.actor.default-dispatcher.max-pool-size-factor") must equal(3.0) getDouble("akka.actor.default-dispatcher.max-pool-size-factor") must equal(3.0)
@ -37,9 +38,15 @@ class ConfigSpec extends AkkaSpec(ConfigFactory.defaultReference) {
getMilliseconds("akka.actor.default-dispatcher.shutdown-timeout") must equal(1 * 1000) getMilliseconds("akka.actor.default-dispatcher.shutdown-timeout") must equal(1 * 1000)
getInt("akka.actor.default-dispatcher.throughput") must equal(5) getInt("akka.actor.default-dispatcher.throughput") must equal(5)
getMilliseconds("akka.actor.default-dispatcher.throughput-deadline-time") must equal(0) getMilliseconds("akka.actor.default-dispatcher.throughput-deadline-time") must equal(0)
getBoolean("akka.actor.serialize-messages") must equal(false) getBoolean("akka.actor.serialize-messages") must equal(false)
settings.SerializeAllMessages must equal(false) settings.SerializeAllMessages must equal(false)
getInt("akka.scheduler.ticksPerWheel") must equal(512)
settings.SchedulerTicksPerWheel must equal(512)
getMilliseconds("akka.scheduler.tickDuration") must equal(100)
settings.SchedulerTickDuration must equal(100 millis)
} }
} }
} }

View file

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com> * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/ */
package akka.dataflow package akka.dataflow

View file

@ -11,12 +11,12 @@ import akka.testkit.{ EventFilter, filterEvents, filterException }
import akka.util.duration._ import akka.util.duration._
import akka.testkit.AkkaSpec import akka.testkit.AkkaSpec
import org.scalatest.junit.JUnitSuite import org.scalatest.junit.JUnitSuite
import java.lang.ArithmeticException
import akka.testkit.DefaultTimeout import akka.testkit.DefaultTimeout
import akka.testkit.TestLatch import akka.testkit.TestLatch
import java.util.concurrent.{ TimeoutException, TimeUnit, CountDownLatch } import java.util.concurrent.{ TimeoutException, TimeUnit, CountDownLatch }
import scala.runtime.NonLocalReturnControl import scala.runtime.NonLocalReturnControl
import akka.pattern.ask import akka.pattern.ask
import java.lang.{ IllegalStateException, ArithmeticException }
object FutureSpec { object FutureSpec {
class TestActor extends Actor { class TestActor extends Actor {
@ -328,6 +328,24 @@ class FutureSpec extends AkkaSpec with Checkers with BeforeAndAfterAll with Defa
Await.result(Future.fold(futures)(0)(_ + _), timeout millis) must be(45) Await.result(Future.fold(futures)(0)(_ + _), timeout millis) must be(45)
} }
"zip" in {
val timeout = 10000 millis
val f = new IllegalStateException("test")
intercept[IllegalStateException] {
Await.result(Promise.failed[String](f) zip Promise.successful("foo"), timeout)
} must be(f)
intercept[IllegalStateException] {
Await.result(Promise.successful("foo") zip Promise.failed[String](f), timeout)
} must be(f)
intercept[IllegalStateException] {
Await.result(Promise.failed[String](f) zip Promise.failed[String](f), timeout)
} must be(f)
Await.result(Promise.successful("foo") zip Promise.successful("foo"), timeout) must be(("foo", "foo"))
}
"fold by composing" in { "fold by composing" in {
val actors = (1 to 10).toList map { _ val actors = (1 to 10).toList map { _
system.actorOf(Props(new Actor { system.actorOf(Props(new Actor {
@ -860,6 +878,12 @@ class FutureSpec extends AkkaSpec with Checkers with BeforeAndAfterAll with Defa
Await.result(p, timeout.duration) must be(result) Await.result(p, timeout.duration) must be(result)
} }
} }
"zip properly" in {
f { (future, result)
Await.result(future zip Promise.successful("foo"), timeout.duration) must be((result, "foo"))
(evaluating { Await.result(future zip Promise.failed(new RuntimeException("ohnoes")), timeout.duration) } must produce[RuntimeException]).getMessage must be("ohnoes")
}
}
"not recover from exception" in { f((future, result) Await.result(future.recover({ case _ "pigdog" }), timeout.duration) must be(result)) } "not recover from exception" in { f((future, result) Await.result(future.recover({ case _ "pigdog" }), timeout.duration) must be(result)) }
"perform action on result" in { "perform action on result" in {
f { (future, result) f { (future, result)
@ -893,6 +917,10 @@ class FutureSpec extends AkkaSpec with Checkers with BeforeAndAfterAll with Defa
"retain exception with map" in { f((future, message) (evaluating { Await.result(future map (_.toString.length), timeout.duration) } must produce[E]).getMessage must be(message)) } "retain exception with map" in { f((future, message) (evaluating { Await.result(future map (_.toString.length), timeout.duration) } must produce[E]).getMessage must be(message)) }
"retain exception with flatMap" in { f((future, message) (evaluating { Await.result(future flatMap (_ Promise.successful[Any]("foo")), timeout.duration) } must produce[E]).getMessage must be(message)) } "retain exception with flatMap" in { f((future, message) (evaluating { Await.result(future flatMap (_ Promise.successful[Any]("foo")), timeout.duration) } must produce[E]).getMessage must be(message)) }
"not perform action with foreach" is pending "not perform action with foreach" is pending
"zip properly" in {
f { (future, message) (evaluating { Await.result(future zip Promise.successful("foo"), timeout.duration) } must produce[E]).getMessage must be(message) }
}
"recover from exception" in { f((future, message) Await.result(future.recover({ case e if e.getMessage == message "pigdog" }), timeout.duration) must be("pigdog")) } "recover from exception" in { f((future, message) Await.result(future.recover({ case e if e.getMessage == message "pigdog" }), timeout.duration) must be("pigdog")) }
"not perform action on result" is pending "not perform action on result" is pending
"project a failure" in { f((future, message) Await.result(future.failed, timeout.duration).getMessage must be(message)) } "project a failure" in { f((future, message) Await.result(future.failed, timeout.duration).getMessage must be(message)) }

View file

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com> * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/ */
package akka.event package akka.event

View file

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com> * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/ */
package akka.event package akka.event

View file

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com> * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/ */
package akka.routing package akka.routing

View file

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com> * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/ */
package akka.routing package akka.routing
@ -32,10 +32,7 @@ object RoutingSpec {
""" """
class TestActor extends Actor { class TestActor extends Actor {
def receive = { def receive = { case _ }
case _
println("Hello")
}
} }
class Echo extends Actor { class Echo extends Actor {

View file

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com> * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/ */
package akka.serialization package akka.serialization

View file

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com> * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/ */
package akka.testkit package akka.testkit

View file

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com> * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/ */
package akka.util package akka.util

View file

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com> * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/ */
package akka.util package akka.util

View file

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com> * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/ */
package akka.util package akka.util

View file

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com> * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/ */
package akka.actor; package akka.actor;

View file

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com> * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/ */
package akka.dispatch; package akka.dispatch;

View file

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com> * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/ */
package akka.dispatch; package akka.dispatch;

View file

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com> * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/ */
package akka.dispatch; package akka.dispatch;

View file

@ -33,6 +33,9 @@ akka {
# See the Akka Documentation for more info about Extensions # See the Akka Documentation for more info about Extensions
extensions = [] extensions = []
# Toggles whether the threads created by this ActorSystem should be daemons or not
daemonic = off
actor { actor {
provider = "akka.actor.LocalActorRefProvider" provider = "akka.actor.LocalActorRefProvider"
@ -155,17 +158,11 @@ akka {
# parameters # parameters
type = "Dispatcher" type = "Dispatcher"
# Name used in log messages and thread names.
name = "default-dispatcher"
# Toggles whether the threads created by this dispatcher should be daemons or not
daemonic = off
# Keep alive time for threads # Keep alive time for threads
keep-alive-time = 60s keep-alive-time = 60s
# minimum number of threads to cap factor-based core number to # minimum number of threads to cap factor-based core number to
core-pool-size-min = 6 core-pool-size-min = 8
# No of core threads ... ceil(available processors * factor) # No of core threads ... ceil(available processors * factor)
core-pool-size-factor = 3.0 core-pool-size-factor = 3.0
@ -175,7 +172,7 @@ akka {
# Hint: max-pool-size is only used for bounded task queues # Hint: max-pool-size is only used for bounded task queues
# minimum number of threads to cap factor-based max number to # minimum number of threads to cap factor-based max number to
max-pool-size-min = 6 max-pool-size-min = 8
# Max no of threads ... ceil(available processors * factor) # Max no of threads ... ceil(available processors * factor)
max-pool-size-factor = 3.0 max-pool-size-factor = 3.0

View file

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com> * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/ */
package akka package akka

View file

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com> * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/ */
package akka.actor package akka.actor

View file

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com> * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/ */
package akka.actor package akka.actor
@ -274,7 +274,7 @@ private[akka] class ActorCell(
} }
@inline @inline
final def dispatcher: MessageDispatcher = system.dispatchers.lookup(props.dispatcher) final val dispatcher: MessageDispatcher = system.dispatchers.lookup(props.dispatcher)
/** /**
* UntypedActorContext impl * UntypedActorContext impl

View file

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com> * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/ */
package akka.actor package akka.actor
import scala.annotation.tailrec import scala.annotation.tailrec

View file

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com> * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/ */
package akka.actor package akka.actor

View file

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com> * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/ */
package akka.actor package akka.actor

View file

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com> * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/ */
package akka.actor package akka.actor
import java.util.regex.Pattern import java.util.regex.Pattern

View file

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com> * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/ */
package akka.actor package akka.actor
@ -97,6 +97,7 @@ object ActorSystem {
final val SchedulerTickDuration = Duration(getMilliseconds("akka.scheduler.tickDuration"), MILLISECONDS) final val SchedulerTickDuration = Duration(getMilliseconds("akka.scheduler.tickDuration"), MILLISECONDS)
final val SchedulerTicksPerWheel = getInt("akka.scheduler.ticksPerWheel") final val SchedulerTicksPerWheel = getInt("akka.scheduler.ticksPerWheel")
final val Daemonicity = getBoolean("akka.daemonic")
if (ConfigVersion != Version) if (ConfigVersion != Version)
throw new ConfigurationException("Akka JAR version [" + Version + "] does not match the provided config version [" + ConfigVersion + "]") throw new ConfigurationException("Akka JAR version [" + Version + "] does not match the provided config version [" + ConfigVersion + "]")
@ -275,6 +276,7 @@ class ActorSystemImpl(val name: String, applicationConfig: Config) extends Actor
import ActorSystem._ import ActorSystem._
final val settings = new Settings(applicationConfig, name) final val settings = new Settings(applicationConfig, name)
final val threadFactory = new MonitorableThreadFactory(name, settings.Daemonicity)
def logConfiguration(): Unit = log.info(settings.toString) def logConfiguration(): Unit = log.info(settings.toString)
@ -361,7 +363,7 @@ class ActorSystemImpl(val name: String, applicationConfig: Config) extends Actor
} }
} }
val dispatchers = new Dispatchers(settings, DefaultDispatcherPrerequisites(eventStream, deadLetterMailbox, scheduler)) val dispatchers = new Dispatchers(settings, DefaultDispatcherPrerequisites(threadFactory, eventStream, deadLetterMailbox, scheduler))
val dispatcher = dispatchers.defaultGlobalDispatcher val dispatcher = dispatchers.defaultGlobalDispatcher
def terminationFuture: Future[Unit] = provider.terminationFuture def terminationFuture: Future[Unit] = provider.terminationFuture
@ -409,18 +411,18 @@ class ActorSystemImpl(val name: String, applicationConfig: Config) extends Actor
* executed upon close(), the task may execute before its timeout. * executed upon close(), the task may execute before its timeout.
*/ */
protected def createScheduler(): Scheduler = { protected def createScheduler(): Scheduler = {
val threadFactory = new MonitorableThreadFactory("DefaultScheduler") val hwt = new HashedWheelTimer(log,
val hwt = new HashedWheelTimer(log, threadFactory, settings.SchedulerTickDuration, settings.SchedulerTicksPerWheel) threadFactory.copy(threadFactory.name + "-scheduler"),
settings.SchedulerTickDuration,
settings.SchedulerTicksPerWheel)
// note that dispatcher is by-name parameter in DefaultScheduler constructor, // note that dispatcher is by-name parameter in DefaultScheduler constructor,
// because dispatcher is not initialized when the scheduler is created // because dispatcher is not initialized when the scheduler is created
def safeDispatcher = { def safeDispatcher = dispatcher match {
if (dispatcher eq null) { case null
val exc = new IllegalStateException("Scheduler is using dispatcher before it has been initialized") val exc = new IllegalStateException("Scheduler is using dispatcher before it has been initialized")
log.error(exc, exc.getMessage) log.error(exc, exc.getMessage)
throw exc throw exc
} else { case dispatcher dispatcher
dispatcher
}
} }
new DefaultScheduler(hwt, log, safeDispatcher) new DefaultScheduler(hwt, log, safeDispatcher)
} }

View file

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com> * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/ */
package akka.actor package akka.actor
import java.net.URI import java.net.URI

View file

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com> * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/ */
package akka.actor package akka.actor

View file

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com> * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/ */
package akka.actor package akka.actor

View file

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com> * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/ */
package akka.actor package akka.actor

View file

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com> * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/ */
package akka.actor package akka.actor

View file

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com> * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/ */
package akka.actor package akka.actor

View file

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com> * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/ */
package akka.actor package akka.actor

View file

@ -123,7 +123,9 @@ trait Cancellable {
* if it does not enqueue a task. Once a task is queued, it MUST be executed or * if it does not enqueue a task. Once a task is queued, it MUST be executed or
* returned from stop(). * returned from stop().
*/ */
class DefaultScheduler(hashedWheelTimer: HashedWheelTimer, log: LoggingAdapter, dispatcher: MessageDispatcher) extends Scheduler with Closeable { class DefaultScheduler(hashedWheelTimer: HashedWheelTimer,
log: LoggingAdapter,
dispatcher: MessageDispatcher) extends Scheduler with Closeable {
def schedule(initialDelay: Duration, delay: Duration, receiver: ActorRef, message: Any): Cancellable = { def schedule(initialDelay: Duration, delay: Duration, receiver: ActorRef, message: Any): Cancellable = {
val continuousCancellable = new ContinuousCancellable val continuousCancellable = new ContinuousCancellable

View file

@ -1,7 +1,7 @@
package akka.actor package akka.actor
/** /**
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com> * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/ */
import akka.japi.{ Creator, Option JOption } import akka.japi.{ Creator, Option JOption }

View file

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com> * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/ */
package akka.actor package akka.actor

View file

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com> * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/ */
package akka package akka

View file

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com> * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/ */
package akka.config package akka.config

View file

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com> * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/ */
package akka.dispatch package akka.dispatch
@ -139,11 +139,6 @@ abstract class MessageDispatcher(val prerequisites: DispatcherPrerequisites) ext
*/ */
protected[akka] def createMailbox(actor: ActorCell): Mailbox protected[akka] def createMailbox(actor: ActorCell): Mailbox
/**
* Name of this dispatcher.
*/
def name: String
/** /**
* Identifier of this dispatcher, corresponds to the full key * Identifier of this dispatcher, corresponds to the full key
* of the dispatcher configuration. * of the dispatcher configuration.
@ -347,7 +342,7 @@ abstract class MessageDispatcherConfigurator(val config: Config, val prerequisit
//Apply the following options to the config if they are present in the config //Apply the following options to the config if they are present in the config
ThreadPoolConfigDispatcherBuilder(createDispatcher, ThreadPoolConfig(daemonic = config getBoolean "daemonic")) ThreadPoolConfigDispatcherBuilder(createDispatcher, ThreadPoolConfig())
.setKeepAliveTime(Duration(config getMilliseconds "keep-alive-time", TimeUnit.MILLISECONDS)) .setKeepAliveTime(Duration(config getMilliseconds "keep-alive-time", TimeUnit.MILLISECONDS))
.setAllowCoreThreadTimeout(config getBoolean "allow-core-timeout") .setAllowCoreThreadTimeout(config getBoolean "allow-core-timeout")
.setCorePoolSizeFromFactor(config getInt "core-pool-size-min", config getDouble "core-pool-size-factor", config getInt "core-pool-size-max") .setCorePoolSizeFromFactor(config getInt "core-pool-size-min", config getDouble "core-pool-size-factor", config getInt "core-pool-size-max")

View file

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com> * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/ */
package akka.dispatch package akka.dispatch
@ -31,14 +31,13 @@ import akka.util.Duration
*/ */
class BalancingDispatcher( class BalancingDispatcher(
_prerequisites: DispatcherPrerequisites, _prerequisites: DispatcherPrerequisites,
_name: String,
_id: String, _id: String,
throughput: Int, throughput: Int,
throughputDeadlineTime: Duration, throughputDeadlineTime: Duration,
mailboxType: MailboxType, mailboxType: MailboxType,
config: ThreadPoolConfig, config: ThreadPoolConfig,
_shutdownTimeout: Duration) _shutdownTimeout: Duration)
extends Dispatcher(_prerequisites, _name, _id, throughput, throughputDeadlineTime, mailboxType, config, _shutdownTimeout) { extends Dispatcher(_prerequisites, _id, throughput, throughputDeadlineTime, mailboxType, config, _shutdownTimeout) {
val buddies = new ConcurrentSkipListSet[ActorCell](akka.util.Helpers.IdentityHashComparator) val buddies = new ConcurrentSkipListSet[ActorCell](akka.util.Helpers.IdentityHashComparator)
val rebalance = new AtomicBoolean(false) val rebalance = new AtomicBoolean(false)

View file

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com> * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/ */
package akka.dispatch package akka.dispatch
@ -24,7 +24,6 @@ import java.util.concurrent._
*/ */
class Dispatcher( class Dispatcher(
_prerequisites: DispatcherPrerequisites, _prerequisites: DispatcherPrerequisites,
val name: String,
val id: String, val id: String,
val throughput: Int, val throughput: Int,
val throughputDeadlineTime: Duration, val throughputDeadlineTime: Duration,
@ -33,7 +32,14 @@ class Dispatcher(
val shutdownTimeout: Duration) val shutdownTimeout: Duration)
extends MessageDispatcher(_prerequisites) { extends MessageDispatcher(_prerequisites) {
protected[akka] val executorServiceFactory = executorServiceFactoryProvider.createExecutorServiceFactory(name) protected[akka] val executorServiceFactory: ExecutorServiceFactory =
executorServiceFactoryProvider.createExecutorServiceFactory(
id,
prerequisites.threadFactory match {
case m: MonitorableThreadFactory m.copy(m.name + "-" + id)
case other other
})
protected[akka] val executorService = new AtomicReference[ExecutorService](new ExecutorServiceDelegate { protected[akka] val executorService = new AtomicReference[ExecutorService](new ExecutorServiceDelegate {
lazy val executor = executorServiceFactory.createExecutorService lazy val executor = executorServiceFactory.createExecutorService
}) })
@ -94,7 +100,7 @@ class Dispatcher(
} else false } else false
} }
override val toString = getClass.getSimpleName + "[" + name + "]" override val toString = getClass.getSimpleName + "[" + id + "]"
} }
object PriorityGenerator { object PriorityGenerator {

View file

@ -1,11 +1,9 @@
/** /**
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com> * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/ */
package akka.dispatch package akka.dispatch
import java.util.concurrent.TimeUnit
import java.util.concurrent.ConcurrentHashMap
import akka.actor.newUuid import akka.actor.newUuid
import akka.util.{ Duration, ReflectiveAccess } import akka.util.{ Duration, ReflectiveAccess }
import akka.actor.ActorSystem import akka.actor.ActorSystem
@ -17,14 +15,17 @@ import com.typesafe.config.ConfigFactory
import akka.config.ConfigurationException import akka.config.ConfigurationException
import akka.event.Logging.Warning import akka.event.Logging.Warning
import akka.actor.Props import akka.actor.Props
import java.util.concurrent.{ ThreadFactory, TimeUnit, ConcurrentHashMap }
trait DispatcherPrerequisites { trait DispatcherPrerequisites {
def threadFactory: ThreadFactory
def eventStream: EventStream def eventStream: EventStream
def deadLetterMailbox: Mailbox def deadLetterMailbox: Mailbox
def scheduler: Scheduler def scheduler: Scheduler
} }
case class DefaultDispatcherPrerequisites( case class DefaultDispatcherPrerequisites(
val threadFactory: ThreadFactory,
val eventStream: EventStream, val eventStream: EventStream,
val deadLetterMailbox: Mailbox, val deadLetterMailbox: Mailbox,
val scheduler: Scheduler) extends DispatcherPrerequisites val scheduler: Scheduler) extends DispatcherPrerequisites
@ -61,7 +62,8 @@ class Dispatchers(val settings: ActorSystem.Settings, val prerequisites: Dispatc
/** /**
* Returns a dispatcher as specified in configuration, or if not defined it uses * Returns a dispatcher as specified in configuration, or if not defined it uses
* the default dispatcher. * the default dispatcher. Please note that this method _may_ create and return a NEW dispatcher,
* _every_ call.
*/ */
def lookup(id: String): MessageDispatcher = lookupConfigurator(id).dispatcher() def lookup(id: String): MessageDispatcher = lookupConfigurator(id).dispatcher()
@ -160,7 +162,6 @@ class DispatcherConfigurator(config: Config, prerequisites: DispatcherPrerequisi
private val instance = private val instance =
configureThreadPool(config, configureThreadPool(config,
threadPoolConfig new Dispatcher(prerequisites, threadPoolConfig new Dispatcher(prerequisites,
config.getString("name"),
config.getString("id"), config.getString("id"),
config.getInt("throughput"), config.getInt("throughput"),
Duration(config.getNanoseconds("throughput-deadline-time"), TimeUnit.NANOSECONDS), Duration(config.getNanoseconds("throughput-deadline-time"), TimeUnit.NANOSECONDS),
@ -185,12 +186,10 @@ class BalancingDispatcherConfigurator(config: Config, prerequisites: DispatcherP
private val instance = private val instance =
configureThreadPool(config, configureThreadPool(config,
threadPoolConfig new BalancingDispatcher(prerequisites, threadPoolConfig new BalancingDispatcher(prerequisites,
config.getString("name"),
config.getString("id"), config.getString("id"),
config.getInt("throughput"), config.getInt("throughput"),
Duration(config.getNanoseconds("throughput-deadline-time"), TimeUnit.NANOSECONDS), Duration(config.getNanoseconds("throughput-deadline-time"), TimeUnit.NANOSECONDS),
mailboxType, mailboxType, threadPoolConfig,
threadPoolConfig,
Duration(config.getMilliseconds("shutdown-timeout"), TimeUnit.MILLISECONDS))).build Duration(config.getMilliseconds("shutdown-timeout"), TimeUnit.MILLISECONDS))).build
/** /**
@ -209,8 +208,10 @@ class PinnedDispatcherConfigurator(config: Config, prerequisites: DispatcherPrer
/** /**
* Creates new dispatcher for each invocation. * Creates new dispatcher for each invocation.
*/ */
override def dispatcher(): MessageDispatcher = override def dispatcher(): MessageDispatcher = configureThreadPool(config,
new PinnedDispatcher(prerequisites, null, config.getString("name"), config.getString("id"), mailboxType, threadPoolConfig
Duration(config.getMilliseconds("shutdown-timeout"), TimeUnit.MILLISECONDS)) new PinnedDispatcher(prerequisites, null, config.getString("id"), mailboxType,
Duration(config.getMilliseconds("shutdown-timeout"), TimeUnit.MILLISECONDS),
threadPoolConfig)).build
} }

View file

@ -1,6 +1,6 @@
/** /**
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com> * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/ */
package akka.dispatch package akka.dispatch
@ -96,14 +96,14 @@ object Futures {
* or the result of the fold. * or the result of the fold.
*/ */
def fold[T <: AnyRef, R <: AnyRef](zero: R, futures: JIterable[Future[T]], fun: akka.japi.Function2[R, T, R], executor: ExecutionContext): Future[R] = def fold[T <: AnyRef, R <: AnyRef](zero: R, futures: JIterable[Future[T]], fun: akka.japi.Function2[R, T, R], executor: ExecutionContext): Future[R] =
Future.fold(scala.collection.JavaConversions.iterableAsScalaIterable(futures))(zero)(fun.apply _)(executor) Future.fold(scala.collection.JavaConversions.iterableAsScalaIterable(futures))(zero)(fun.apply)(executor)
/** /**
* Java API. * Java API.
* Initiates a fold over the supplied futures where the fold-zero is the result value of the Future that's completed first * Initiates a fold over the supplied futures where the fold-zero is the result value of the Future that's completed first
*/ */
def reduce[T <: AnyRef, R >: T](futures: JIterable[Future[T]], fun: akka.japi.Function2[R, T, T], executor: ExecutionContext): Future[R] = def reduce[T <: AnyRef, R >: T](futures: JIterable[Future[T]], fun: akka.japi.Function2[R, T, R], executor: ExecutionContext): Future[R] =
Future.reduce(scala.collection.JavaConversions.iterableAsScalaIterable(futures))(fun.apply _)(executor) Future.reduce[T, R](scala.collection.JavaConversions.iterableAsScalaIterable(futures))(fun.apply)(executor)
/** /**
* Java API. * Java API.
@ -224,9 +224,9 @@ object Future {
* val result = Await.result(Futures.reduce(futures)(_ + _), 5 seconds) * val result = Await.result(Futures.reduce(futures)(_ + _), 5 seconds)
* </pre> * </pre>
*/ */
def reduce[T, R >: T](futures: Traversable[Future[T]])(op: (R, T) T)(implicit executor: ExecutionContext): Future[R] = { def reduce[T, R >: T](futures: Traversable[Future[T]])(op: (R, T) R)(implicit executor: ExecutionContext): Future[R] = {
if (futures.isEmpty) Promise[R].failure(new NoSuchElementException("reduce attempted on empty collection")) if (futures.isEmpty) Promise[R].failure(new NoSuchElementException("reduce attempted on empty collection"))
else sequence(futures).map(_ reduce op) else sequence(futures).map(_ reduceLeft op)
} }
/** /**
* Transforms a Traversable[A] into a Future[Traversable[B]] using the provided Function A Future[B]. * Transforms a Traversable[A] into a Future[Traversable[B]] using the provided Function A Future[B].
@ -346,6 +346,21 @@ sealed trait Future[+T] extends japi.Future[T] with Await.Awaitable[T] {
case _ source case _ source
} }
/**
* @returns a new Future that will contain a tuple containing the successful result of this and that Future.
* If this or that fail, they will race to complete the returned Future with their failure.
* The returned Future will not be completed if neither this nor that are completed.
*/
def zip[U](that: Future[U]): Future[(T, U)] = {
val p = Promise[(T, U)]()
onComplete {
case Left(t) p failure t
case Right(r) that onSuccess { case r2 p success ((r, r2)) }
}
that onFailure { case f p failure f }
p
}
/** /**
* For use only within a Future.flow block or another compatible Delimited Continuations reset block. * For use only within a Future.flow block or another compatible Delimited Continuations reset block.
* *
@ -357,7 +372,7 @@ sealed trait Future[+T] extends japi.Future[T] with Await.Awaitable[T] {
/** /**
* Tests whether this Future has been completed. * Tests whether this Future has been completed.
*/ */
final def isCompleted: Boolean = value.isDefined def isCompleted: Boolean
/** /**
* The contained value of this Future. Before this Future is completed * The contained value of this Future. Before this Future is completed
@ -676,23 +691,7 @@ trait Promise[T] extends Future[T] {
//Companion object to FState, just to provide a cheap, immutable default entry //Companion object to FState, just to provide a cheap, immutable default entry
private[dispatch] object DefaultPromise { private[dispatch] object DefaultPromise {
def EmptyPending[T](): FState[T] = emptyPendingValue.asInstanceOf[FState[T]] def EmptyPending[T](): List[T] = Nil
/**
* Represents the internal state of the DefaultCompletableFuture
*/
sealed trait FState[+T] { def value: Option[Either[Throwable, T]] }
case class Pending[T](listeners: List[Either[Throwable, T] Unit] = Nil) extends FState[T] {
def value: Option[Either[Throwable, T]] = None
}
case class Success[T](value: Option[Either[Throwable, T]] = None) extends FState[T] {
def result: T = value.get.right.get
}
case class Failure[T](value: Option[Either[Throwable, T]] = None) extends FState[T] {
def exception: Throwable = value.get.left.get
}
private val emptyPendingValue = Pending[Nothing](Nil)
} }
/** /**
@ -701,28 +700,25 @@ private[dispatch] object DefaultPromise {
class DefaultPromise[T](implicit val executor: ExecutionContext) extends AbstractPromise with Promise[T] { class DefaultPromise[T](implicit val executor: ExecutionContext) extends AbstractPromise with Promise[T] {
self self
import DefaultPromise.{ FState, Success, Failure, Pending }
protected final def tryAwait(atMost: Duration): Boolean = { protected final def tryAwait(atMost: Duration): Boolean = {
Future.blocking Future.blocking
@tailrec @tailrec
def awaitUnsafe(waitTimeNanos: Long): Boolean = { def awaitUnsafe(waitTimeNanos: Long): Boolean = {
if (value.isEmpty && waitTimeNanos > 0) { if (!isCompleted && waitTimeNanos > 0) {
val ms = NANOSECONDS.toMillis(waitTimeNanos) val ms = NANOSECONDS.toMillis(waitTimeNanos)
val ns = (waitTimeNanos % 1000000l).toInt //As per object.wait spec val ns = (waitTimeNanos % 1000000l).toInt //As per object.wait spec
val start = System.nanoTime() val start = System.nanoTime()
try { synchronized { if (value.isEmpty) wait(ms, ns) } } catch { case e: InterruptedException } try { synchronized { if (!isCompleted) wait(ms, ns) } } catch { case e: InterruptedException }
awaitUnsafe(waitTimeNanos - (System.nanoTime() - start)) awaitUnsafe(waitTimeNanos - (System.nanoTime() - start))
} else } else isCompleted
value.isDefined
} }
awaitUnsafe(if (atMost.isFinite) atMost.toNanos else Long.MaxValue) awaitUnsafe(if (atMost.isFinite) atMost.toNanos else Long.MaxValue)
} }
def ready(atMost: Duration)(implicit permit: CanAwait): this.type = def ready(atMost: Duration)(implicit permit: CanAwait): this.type =
if (value.isDefined || tryAwait(atMost)) this if (isCompleted || tryAwait(atMost)) this
else throw new TimeoutException("Futures timed out after [" + atMost.toMillis + "] milliseconds") else throw new TimeoutException("Futures timed out after [" + atMost.toMillis + "] milliseconds")
def result(atMost: Duration)(implicit permit: CanAwait): T = def result(atMost: Duration)(implicit permit: CanAwait): T =
@ -731,16 +727,24 @@ class DefaultPromise[T](implicit val executor: ExecutionContext) extends Abstrac
case Right(r) r case Right(r) r
} }
def value: Option[Either[Throwable, T]] = getState.value def value: Option[Either[Throwable, T]] = getState match {
case _: List[_] None
case c: Either[_, _] Some(c.asInstanceOf[Either[Throwable, T]])
}
def isCompleted(): Boolean = getState match {
case _: Either[_, _] true
case _ false
}
@inline @inline
private[this] final def updater = AbstractPromise.updater.asInstanceOf[AtomicReferenceFieldUpdater[AbstractPromise, FState[T]]] private[this] final def updater = AbstractPromise.updater.asInstanceOf[AtomicReferenceFieldUpdater[AbstractPromise, AnyRef]]
@inline @inline
protected final def updateState(oldState: FState[T], newState: FState[T]): Boolean = updater.compareAndSet(this, oldState, newState) protected final def updateState(oldState: AnyRef, newState: AnyRef): Boolean = updater.compareAndSet(this, oldState, newState)
@inline @inline
protected final def getState: FState[T] = updater.get(this) protected final def getState: AnyRef = updater.get(this)
def tryComplete(value: Either[Throwable, T]): Boolean = { def tryComplete(value: Either[Throwable, T]): Boolean = {
val callbacks: List[Either[Throwable, T] Unit] = { val callbacks: List[Either[Throwable, T] Unit] = {
@ -748,9 +752,9 @@ class DefaultPromise[T](implicit val executor: ExecutionContext) extends Abstrac
@tailrec @tailrec
def tryComplete(v: Either[Throwable, T]): List[Either[Throwable, T] Unit] = { def tryComplete(v: Either[Throwable, T]): List[Either[Throwable, T] Unit] = {
getState match { getState match {
case cur @ Pending(listeners) case raw: List[_]
if (updateState(cur, if (v.isLeft) Failure(Some(v)) else Success(Some(v)))) listeners val cur = raw.asInstanceOf[List[Either[Throwable, T] Unit]]
else tryComplete(v) if (updateState(cur, v)) cur else tryComplete(v)
case _ null case _ null
} }
} }
@ -769,23 +773,21 @@ class DefaultPromise[T](implicit val executor: ExecutionContext) extends Abstrac
def onComplete(func: Either[Throwable, T] Unit): this.type = { def onComplete(func: Either[Throwable, T] Unit): this.type = {
@tailrec //Returns whether the future has already been completed or not @tailrec //Returns whether the future has already been completed or not
def tryAddCallback(): Boolean = { def tryAddCallback(): Either[Throwable, T] = {
val cur = getState val cur = getState
cur match { cur match {
case _: Success[_] | _: Failure[_] true case r: Either[_, _] r.asInstanceOf[Either[Throwable, T]]
case p: Pending[_] case listeners: List[_] if (updateState(listeners, func :: listeners)) null else tryAddCallback()
val pt = p.asInstanceOf[Pending[T]]
if (updateState(pt, pt.copy(listeners = func :: pt.listeners))) false else tryAddCallback()
} }
} }
if (tryAddCallback()) { tryAddCallback() match {
val result = value.get case null this
Future.dispatchTask(() notifyCompleted(func, result)) case completed
} Future.dispatchTask(() notifyCompleted(func, completed))
this this
} }
}
private final def notifyCompleted(func: Either[Throwable, T] Unit, result: Either[Throwable, T]) { private final def notifyCompleted(func: Either[Throwable, T] Unit, result: Either[Throwable, T]) {
try { func(result) } catch { case e logError("Future onComplete-callback raised an exception", e) } try { func(result) } catch { case e logError("Future onComplete-callback raised an exception", e) }
@ -805,7 +807,7 @@ final class KeptPromise[T](suppliedValue: Either[Throwable, T])(implicit val exe
Future dispatchTask (() func(completedAs)) Future dispatchTask (() func(completedAs))
this this
} }
def isCompleted(): Boolean = true
def ready(atMost: Duration)(implicit permit: CanAwait): this.type = this def ready(atMost: Duration)(implicit permit: CanAwait): this.type = this
def result(atMost: Duration)(implicit permit: CanAwait): T = value.get match { def result(atMost: Duration)(implicit permit: CanAwait): T = value.get match {
case Left(e) throw e case Left(e) throw e

View file

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com> * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/ */
package akka.dispatch package akka.dispatch

View file

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com> * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/ */
package akka.dispatch package akka.dispatch
@ -21,17 +21,16 @@ import java.util.concurrent.TimeUnit
class PinnedDispatcher( class PinnedDispatcher(
_prerequisites: DispatcherPrerequisites, _prerequisites: DispatcherPrerequisites,
_actor: ActorCell, _actor: ActorCell,
_name: String,
_id: String, _id: String,
_mailboxType: MailboxType, _mailboxType: MailboxType,
_shutdownTimeout: Duration) _shutdownTimeout: Duration,
_threadPoolConfig: ThreadPoolConfig = ThreadPoolConfig())
extends Dispatcher(_prerequisites, extends Dispatcher(_prerequisites,
_name,
_id, _id,
Int.MaxValue, Int.MaxValue,
Duration.Zero, Duration.Zero,
_mailboxType, _mailboxType,
ThreadPoolConfig(allowCorePoolTimeout = true, corePoolSize = 1, maxPoolSize = 1), _threadPoolConfig.copy(allowCorePoolTimeout = true, corePoolSize = 1, maxPoolSize = 1),
_shutdownTimeout) { _shutdownTimeout) {
@volatile @volatile

View file

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com> * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/ */
package akka.dispatch package akka.dispatch
@ -16,6 +16,7 @@ object ThreadPoolConfig {
val defaultCorePoolSize: Int = 16 val defaultCorePoolSize: Int = 16
val defaultMaxPoolSize: Int = 128 val defaultMaxPoolSize: Int = 128
val defaultTimeout: Duration = Duration(60000L, TimeUnit.MILLISECONDS) val defaultTimeout: Duration = Duration(60000L, TimeUnit.MILLISECONDS)
val defaultRejectionPolicy: RejectedExecutionHandler = new SaneRejectedExecutionHandler()
def scaledPoolSize(floor: Int, multiplier: Double, ceiling: Int): Int = { def scaledPoolSize(floor: Int, multiplier: Double, ceiling: Int): Int = {
import scala.math.{ min, max } import scala.math.{ min, max }
@ -54,7 +55,7 @@ trait ExecutorServiceFactory {
* Generic way to specify an ExecutorService to a Dispatcher, create it with the given name if desired * Generic way to specify an ExecutorService to a Dispatcher, create it with the given name if desired
*/ */
trait ExecutorServiceFactoryProvider { trait ExecutorServiceFactoryProvider {
def createExecutorServiceFactory(name: String): ExecutorServiceFactory def createExecutorServiceFactory(name: String, threadFactory: ThreadFactory): ExecutorServiceFactory
} }
/** /**
@ -65,16 +66,24 @@ case class ThreadPoolConfig(allowCorePoolTimeout: Boolean = ThreadPoolConfig.def
maxPoolSize: Int = ThreadPoolConfig.defaultMaxPoolSize, maxPoolSize: Int = ThreadPoolConfig.defaultMaxPoolSize,
threadTimeout: Duration = ThreadPoolConfig.defaultTimeout, threadTimeout: Duration = ThreadPoolConfig.defaultTimeout,
queueFactory: ThreadPoolConfig.QueueFactory = ThreadPoolConfig.linkedBlockingQueue(), queueFactory: ThreadPoolConfig.QueueFactory = ThreadPoolConfig.linkedBlockingQueue(),
daemonic: Boolean = false) rejectionPolicy: RejectedExecutionHandler = ThreadPoolConfig.defaultRejectionPolicy)
extends ExecutorServiceFactoryProvider { extends ExecutorServiceFactoryProvider {
class ThreadPoolExecutorServiceFactory(val threadFactory: ThreadFactory) extends ExecutorServiceFactory { class ThreadPoolExecutorServiceFactory(val threadFactory: ThreadFactory) extends ExecutorServiceFactory {
def createExecutorService: ExecutorService = { def createExecutorService: ExecutorService = {
val service = new ThreadPoolExecutor(corePoolSize, maxPoolSize, threadTimeout.length, threadTimeout.unit, queueFactory(), threadFactory, new SaneRejectedExecutionHandler) val service = new ThreadPoolExecutor(
corePoolSize,
maxPoolSize,
threadTimeout.length,
threadTimeout.unit,
queueFactory(),
threadFactory,
rejectionPolicy)
service.allowCoreThreadTimeOut(allowCorePoolTimeout) service.allowCoreThreadTimeOut(allowCorePoolTimeout)
service service
} }
} }
final def createExecutorServiceFactory(name: String): ExecutorServiceFactory = new ThreadPoolExecutorServiceFactory(new MonitorableThreadFactory(name, daemonic)) final def createExecutorServiceFactory(name: String, threadFactory: ThreadFactory): ExecutorServiceFactory =
new ThreadPoolExecutorServiceFactory(threadFactory)
} }
trait DispatcherBuilder { trait DispatcherBuilder {
@ -90,7 +99,7 @@ object ThreadPoolConfigDispatcherBuilder {
*/ */
case class ThreadPoolConfigDispatcherBuilder(dispatcherFactory: (ThreadPoolConfig) MessageDispatcher, config: ThreadPoolConfig) extends DispatcherBuilder { case class ThreadPoolConfigDispatcherBuilder(dispatcherFactory: (ThreadPoolConfig) MessageDispatcher, config: ThreadPoolConfig) extends DispatcherBuilder {
import ThreadPoolConfig._ import ThreadPoolConfig._
def build = dispatcherFactory(config) def build: MessageDispatcher = dispatcherFactory(config)
def withNewThreadPoolWithCustomBlockingQueue(newQueueFactory: QueueFactory): ThreadPoolConfigDispatcherBuilder = def withNewThreadPoolWithCustomBlockingQueue(newQueueFactory: QueueFactory): ThreadPoolConfigDispatcherBuilder =
this.copy(config = config.copy(queueFactory = newQueueFactory)) this.copy(config = config.copy(queueFactory = newQueueFactory))
@ -143,16 +152,20 @@ case class ThreadPoolConfigDispatcherBuilder(dispatcherFactory: (ThreadPoolConfi
def configure(fs: Option[Function[ThreadPoolConfigDispatcherBuilder, ThreadPoolConfigDispatcherBuilder]]*): ThreadPoolConfigDispatcherBuilder = fs.foldLeft(this)((c, f) f.map(_(c)).getOrElse(c)) def configure(fs: Option[Function[ThreadPoolConfigDispatcherBuilder, ThreadPoolConfigDispatcherBuilder]]*): ThreadPoolConfigDispatcherBuilder = fs.foldLeft(this)((c, f) f.map(_(c)).getOrElse(c))
} }
class MonitorableThreadFactory(val name: String, val daemonic: Boolean = false) extends ThreadFactory { object MonitorableThreadFactory {
val doNothing: Thread.UncaughtExceptionHandler =
new Thread.UncaughtExceptionHandler() { def uncaughtException(thread: Thread, cause: Throwable) = () }
}
case class MonitorableThreadFactory(name: String,
daemonic: Boolean,
exceptionHandler: Thread.UncaughtExceptionHandler = MonitorableThreadFactory.doNothing)
extends ThreadFactory {
protected val counter = new AtomicLong protected val counter = new AtomicLong
protected val doNothing: Thread.UncaughtExceptionHandler =
new Thread.UncaughtExceptionHandler() {
def uncaughtException(thread: Thread, cause: Throwable) = {}
}
def newThread(runnable: Runnable) = { def newThread(runnable: Runnable) = {
val t = new Thread(runnable, name + counter.incrementAndGet()) val t = new Thread(runnable, name + counter.incrementAndGet())
t.setUncaughtExceptionHandler(doNothing) t.setUncaughtExceptionHandler(exceptionHandler)
t.setDaemon(daemonic) t.setDaemon(daemonic)
t t
} }
@ -203,54 +216,3 @@ class SaneRejectedExecutionHandler extends RejectedExecutionHandler {
else runnable.run() else runnable.run()
} }
} }
/**
* Commented out pending discussion with Doug Lea
*
* case class ForkJoinPoolConfig(targetParallelism: Int = Runtime.getRuntime.availableProcessors()) extends ExecutorServiceFactoryProvider {
* final def createExecutorServiceFactory(name: String): ExecutorServiceFactory = new ExecutorServiceFactory {
* def createExecutorService: ExecutorService = {
* new ForkJoinPool(targetParallelism) with ExecutorService {
* setAsyncMode(true)
* setMaintainsParallelism(true)
*
* override final def execute(r: Runnable) {
* r match {
* case fjmbox: FJMailbox
* //fjmbox.fjTask.reinitialize()
* Thread.currentThread match {
* case fjwt: ForkJoinWorkerThread if fjwt.getPool eq this
* fjmbox.fjTask.fork() //We should do fjwt.pushTask(fjmbox.fjTask) but it's package protected
* case _ super.execute[Unit](fjmbox.fjTask)
* }
* case _
* super.execute(r)
* }
* }
*
* import java.util.{ Collection JCollection }
*
* def invokeAny[T](callables: JCollection[_ <: Callable[T]]) =
* throw new UnsupportedOperationException("invokeAny. NOT!")
*
* def invokeAny[T](callables: JCollection[_ <: Callable[T]], l: Long, timeUnit: TimeUnit) =
* throw new UnsupportedOperationException("invokeAny. NOT!")
*
* def invokeAll[T](callables: JCollection[_ <: Callable[T]], l: Long, timeUnit: TimeUnit) =
* throw new UnsupportedOperationException("invokeAny. NOT!")
* }
* }
* }
* }
*
* trait FJMailbox { self: Mailbox
* final val fjTask = new ForkJoinTask[Unit] with Runnable {
* private[this] var result: Unit = ()
* final def getRawResult() = result
* final def setRawResult(v: Unit) { result = v }
* final def exec() = { self.run(); true }
* final def run() { invoke() }
* }
* }
*
*/

View file

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com> * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/ */
package akka.dispatch.japi package akka.dispatch.japi

View file

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com> * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/ */
package akka.event package akka.event

View file

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com> * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/ */
package akka.event package akka.event

View file

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com> * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/ */
package akka.event package akka.event

View file

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com> * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/ */
package akka.event package akka.event

View file

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com> * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/ */
package akka.event package akka.event

View file

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com> * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/ */
package akka.japi package akka.japi

View file

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com> * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/ */
package akka.routing package akka.routing

View file

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com> * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/ */
package akka.routing package akka.routing

View file

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com> * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/ */
package akka.routing package akka.routing

View file

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com> * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/ */
package akka.routing package akka.routing

View file

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com> * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/ */
package akka package akka

View file

@ -1,7 +1,7 @@
package akka.serialization package akka.serialization
/** /**
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com> * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/ */
import akka.actor.Actor import akka.actor.Actor

View file

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com> * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/ */
package akka.serialization package akka.serialization

View file

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com> * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/ */
package akka.serialization package akka.serialization

View file

@ -1,7 +1,7 @@
package akka.serialization package akka.serialization
/** /**
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com> * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/ */
import java.io.{ ObjectOutputStream, ByteArrayOutputStream, ObjectInputStream, ByteArrayInputStream } import java.io.{ ObjectOutputStream, ByteArrayOutputStream, ObjectInputStream, ByteArrayInputStream }

View file

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com> * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/ */
package akka.util package akka.util

View file

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com> * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/ */
package akka.util package akka.util

View file

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com> * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/ */
package akka.util package akka.util

View file

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com> * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/ */
package akka.util package akka.util

View file

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com> * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/ */
package akka.util package akka.util

View file

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com> * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/ */
package akka.util package akka.util

View file

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com> * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/ */
package akka.util package akka.util

View file

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com> * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/ */
package akka.util package akka.util

View file

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com> * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/ */
package akka.util package akka.util

View file

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com> * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/ */
package akka.util package akka.util

View file

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com> * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/ */
package akka.util package akka.util

View file

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com> * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/ */
package akka.util package akka.util

Some files were not shown because too many files have changed in this diff Show more