From bb7c5f3234a2b91d610a266c9daf0d90a744bc46 Mon Sep 17 00:00:00 2001 From: jboner Date: Fri, 20 Nov 2009 08:29:31 +0100 Subject: [PATCH 01/20] cleaned up supervisor and actor api, breaking changes --- .../akka_samples_lift_war_exploded.xml | 105 ---- ...om_google_protobuf_protobuf_java_2_1_0.xml | 13 - .../Maven__net_liftweb_lift_actor_1_1_M6.xml | 13 - .../Maven__net_liftweb_lift_webkit_1_1_M6.xml | 13 - .../Maven__org_mortbay_jetty_jetty_6_1_22.xml | 13 - ...n__org_mortbay_jetty_jetty_util_6_1_22.xml | 13 - ...mortbay_jetty_servlet_api_2_5_20081211.xml | 13 - .idea/workspace.xml | 223 +++++--- .../src/main/scala/actor/ActiveObject.scala | 10 +- akka-actors/src/main/scala/actor/Actor.scala | 29 +- .../src/main/scala/actor/Scheduler.scala | 6 +- .../src/main/scala/actor/Supervisor.scala | 87 ++-- .../ActiveObjectGuiceConfigurator.scala | 2 +- .../EventBasedSingleThreadActorTest.scala | 12 +- ...EventBasedSingleThreadDispatcherTest.scala | 6 +- .../scala/EventBasedThreadPoolActorTest.scala | 12 +- .../EventBasedThreadPoolDispatcherTest.scala | 6 +- .../src/test/scala/InMemoryActorTest.scala | 4 +- .../src/test/scala/RemoteActorTest.scala | 12 +- .../src/test/scala/RemoteSupervisorTest.scala | 479 +++++++++--------- .../src/test/scala/SchedulerTest.scala | 2 +- .../src/test/scala/SupervisorTest.scala | 53 +- .../src/test/scala/ThreadBasedActorTest.scala | 12 +- .../scala/ThreadBasedDispatcherTest.scala | 6 +- akka-amqp/src/main/scala/AMQP.scala | 10 +- akka-amqp/src/main/scala/ExampleSession.scala | 6 +- .../akka/api/InMemNestedStateTest.java | 8 +- .../akka/api/InMemoryStateTest.java | 20 +- .../scala/CassandraPersistentActorSpec.scala | 4 +- .../test/scala/MongoPersistentActorSpec.scala | 4 +- .../src/main/scala/akka/SimpleService.scala | 4 +- .../main/scala/bootstrap/liftweb/Boot.scala | 33 +- .../src/main/scala/SimpleService.scala | 38 +- .../src/main/scala/SimpleService.scala | 104 ++-- akka-security/src/main/scala/Security.scala | 18 +- .../actor/ActiveObject.scala.html | 4 +- .../actor/Actor.scala.html | 4 +- .../actor/Scheduler.scala.html | 4 +- .../actor/Supervisor.scala.html | 2 +- .../scalablesolutions/akka/actor/Actor.html | 2 +- .../akka/actor/ScheduleActor.html | 2 +- .../akka/actor/Scheduler$object.html | 2 +- .../akka/actor/Supervisor.html | 2 +- docs/scaladocs-akka-amqp/AMQP.scala.html | 8 +- .../ExampleSession.scala.html | 6 +- .../akka/amqp/AMQP$object.html | 2 +- .../Security.scala.html | 4 +- .../akka/security/AuthenticationActor.html | 2 +- .../security/BasicAuthenticationActor.html | 2 +- .../security/DigestAuthenticationActor.html | 2 +- .../security/SpnegoAuthenticationActor.html | 2 +- 51 files changed, 637 insertions(+), 806 deletions(-) delete mode 100644 .idea/libraries/Maven__com_google_protobuf_protobuf_java_2_1_0.xml delete mode 100644 .idea/libraries/Maven__net_liftweb_lift_actor_1_1_M6.xml delete mode 100644 .idea/libraries/Maven__net_liftweb_lift_webkit_1_1_M6.xml delete mode 100644 .idea/libraries/Maven__org_mortbay_jetty_jetty_6_1_22.xml delete mode 100644 .idea/libraries/Maven__org_mortbay_jetty_jetty_util_6_1_22.xml delete mode 100644 .idea/libraries/Maven__org_mortbay_jetty_servlet_api_2_5_20081211.xml diff --git a/.idea/artifacts/akka_samples_lift_war_exploded.xml b/.idea/artifacts/akka_samples_lift_war_exploded.xml index 0cff3865c5..9f98b24e5b 100644 --- a/.idea/artifacts/akka_samples_lift_war_exploded.xml +++ b/.idea/artifacts/akka_samples_lift_war_exploded.xml @@ -7,111 +7,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/.idea/libraries/Maven__com_google_protobuf_protobuf_java_2_1_0.xml b/.idea/libraries/Maven__com_google_protobuf_protobuf_java_2_1_0.xml deleted file mode 100644 index efe007a64e..0000000000 --- a/.idea/libraries/Maven__com_google_protobuf_protobuf_java_2_1_0.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Maven__net_liftweb_lift_actor_1_1_M6.xml b/.idea/libraries/Maven__net_liftweb_lift_actor_1_1_M6.xml deleted file mode 100644 index 82142fbc1f..0000000000 --- a/.idea/libraries/Maven__net_liftweb_lift_actor_1_1_M6.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Maven__net_liftweb_lift_webkit_1_1_M6.xml b/.idea/libraries/Maven__net_liftweb_lift_webkit_1_1_M6.xml deleted file mode 100644 index a77e2cfc9b..0000000000 --- a/.idea/libraries/Maven__net_liftweb_lift_webkit_1_1_M6.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Maven__org_mortbay_jetty_jetty_6_1_22.xml b/.idea/libraries/Maven__org_mortbay_jetty_jetty_6_1_22.xml deleted file mode 100644 index 91ee03e168..0000000000 --- a/.idea/libraries/Maven__org_mortbay_jetty_jetty_6_1_22.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Maven__org_mortbay_jetty_jetty_util_6_1_22.xml b/.idea/libraries/Maven__org_mortbay_jetty_jetty_util_6_1_22.xml deleted file mode 100644 index bf562dadbf..0000000000 --- a/.idea/libraries/Maven__org_mortbay_jetty_jetty_util_6_1_22.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Maven__org_mortbay_jetty_servlet_api_2_5_20081211.xml b/.idea/libraries/Maven__org_mortbay_jetty_servlet_api_2_5_20081211.xml deleted file mode 100644 index 4863239c0e..0000000000 --- a/.idea/libraries/Maven__org_mortbay_jetty_servlet_api_2_5_20081211.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/workspace.xml b/.idea/workspace.xml index 7637ebbe50..0dc072b32f 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -2,7 +2,57 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -62,91 +112,91 @@ - - + + - + - - + + - + - - + + - + - - + + - + - - + + - + - - + + - + - - + + - + - - + + - + - - + + - + - - + + - + @@ -162,19 +212,22 @@ @@ -372,7 +425,8 @@ - + + @@ -384,7 +438,6 @@ - @@ -419,114 +472,116 @@ - - - - - - - - - - - - - - - + - + - + - + - + - + - - + + + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + + + + + + + + + + + + + + + diff --git a/akka-actors/src/main/scala/actor/ActiveObject.scala b/akka-actors/src/main/scala/actor/ActiveObject.scala index 2e7ff1249d..dd14cda0a5 100644 --- a/akka-actors/src/main/scala/actor/ActiveObject.scala +++ b/akka-actors/src/main/scala/actor/ActiveObject.scala @@ -127,11 +127,9 @@ object ActiveObject { private[akka] def supervise(restartStrategy: RestartStrategy, components: List[Supervise]): Supervisor = { - object factory extends SupervisorFactory { - override def getSupervisorConfig = SupervisorConfig(restartStrategy, components) - } - val supervisor = factory.newSupervisor - supervisor ! StartSupervisor + val factory = SupervisorFactory(SupervisorConfig(restartStrategy, components)) + val supervisor = factory.newInstance + supervisor.start supervisor } } @@ -325,7 +323,7 @@ private[akka] class Dispatcher(val callbacks: Option[RestartCallbacks]) extends //if (initTxState.isDefined) initTxState.get.setAccessible(true) } - override def receive: PartialFunction[Any, Unit] = { + def receive: PartialFunction[Any, Unit] = { case Invocation(joinPoint, isOneWay, _) => if (Actor.SERIALIZE_MESSAGES) serializeArguments(joinPoint) if (isOneWay) joinPoint.proceed diff --git a/akka-actors/src/main/scala/actor/Actor.scala b/akka-actors/src/main/scala/actor/Actor.scala index 358e27bd54..5aba208a28 100644 --- a/akka-actors/src/main/scala/actor/Actor.scala +++ b/akka-actors/src/main/scala/actor/Actor.scala @@ -70,7 +70,14 @@ object Actor { /** * Actor base trait that should be extended by or mixed to create an Actor with the semantics of the 'Actor Model': * http://en.wikipedia.org/wiki/Actor_model - * + *

+ * An actor has a well-defined (non-cyclic) life-cycle. + *

+ * => NEW (newly created actor) - can't receive messages (yet)
+ *     => STARTED (when 'start' is invoked) - can receive messages
+ *         => SHUT DOWN (when 'exit' is invoked) - can't do anything
+ * 
+ * * @author Jonas Bonér */ trait Actor extends Logging with TransactionManagement { @@ -81,6 +88,7 @@ trait Actor extends Logging with TransactionManagement { // private fields @volatile private var _isRunning: Boolean = false + @volatile private var _isShutDown: Boolean = false private var _hotswap: Option[PartialFunction[Any, Unit]] = None private var _config: Option[AnyRef] = None private val _remoteFlagLock = new ReadWriteLock @@ -144,7 +152,6 @@ trait Actor extends Logging with TransactionManagement { protected[akka] var messageDispatcher: MessageDispatcher = { val dispatcher = Dispatchers.newEventBasedThreadPoolDispatcher(getClass.getName) _mailbox = dispatcher.messageQueue - dispatcher.registerHandler(this, new ActorMessageInvoker(this)) dispatcher } @@ -201,7 +208,7 @@ trait Actor extends Logging with TransactionManagement { *

* Example code: *

-   *   def receive: PartialFunction[Any, Unit] = {
+   *   def receive = {
    *     case Ping =>
    *       println("got a ping")
    *       reply("pong")
@@ -264,7 +271,9 @@ trait Actor extends Logging with TransactionManagement {
    * Starts up the actor and its message queue.
    */
   def start = synchronized  {
+    if (_isShutDown) throw new IllegalStateException("Can't restart an actor that have been shut down with 'exit'")
     if (!_isRunning) {
+      dispatcher.registerHandler(this, new ActorMessageInvoker(this))
       messageDispatcher.start
       _isRunning = true
       //if (isTransactional) this !! TransactionalInit
@@ -273,14 +282,15 @@ trait Actor extends Logging with TransactionManagement {
   }
 
   /**
-   * Stops the actor and its message queue.
+   * Shuts down the actor its dispatcher and message queue.
    */
-  def stop = synchronized {
+  def exit = synchronized {
     if (_isRunning) {
-      dispatcher.unregisterHandler(this)
-      if (dispatcher.isInstanceOf[ThreadBasedDispatcher]) dispatcher.shutdown
+      messageDispatcher.unregisterHandler(this)
+      if (messageDispatcher.isInstanceOf[ThreadBasedDispatcher]) messageDispatcher.shutdown
       // FIXME: Need to do reference count to know if EventBasedThreadPoolDispatcher and EventBasedSingleThreadDispatcher can be shut down
       _isRunning = false
+      _isShutDown = true
       shutdown
     }
   }
@@ -356,7 +366,10 @@ trait Actor extends Logging with TransactionManagement {
     case Some(future) => future.completeWithResult(message)
   }
 
-  def dispatcher = messageDispatcher
+  /**
+   * Get the dispatcher for this actor.
+   */
+  def dispatcher = synchronized { messageDispatcher }
 
   /**
    * Sets the dispatcher for this actor. Needs to be invoked before the actor is started.
diff --git a/akka-actors/src/main/scala/actor/Scheduler.scala b/akka-actors/src/main/scala/actor/Scheduler.scala
index df4d41ff40..6266c17942 100644
--- a/akka-actors/src/main/scala/actor/Scheduler.scala
+++ b/akka-actors/src/main/scala/actor/Scheduler.scala
@@ -30,11 +30,11 @@ case class SchedulerException(msg: String, e: Throwable) extends RuntimeExceptio
 class ScheduleActor(val receiver: Actor, val future: ScheduledFuture[AnyRef]) extends Actor with Logging {
   lifeCycle = Some(LifeCycle(Permanent))
 
-  def receive: PartialFunction[Any, Unit] = {
+  def receive = {
     case UnSchedule =>
       Scheduler.stopSupervising(this)
       future.cancel(true)
-      stop
+      exit
   }
 }
 
@@ -69,7 +69,7 @@ object Scheduler extends Actor {
     service.shutdown
   }
 
-  def receive: PartialFunction[Any, Unit] = {
+  def receive = {
     case _ => {} // ignore all messages
   }
 }
diff --git a/akka-actors/src/main/scala/actor/Supervisor.scala b/akka-actors/src/main/scala/actor/Supervisor.scala
index 429677d6f0..d08150364e 100644
--- a/akka-actors/src/main/scala/actor/Supervisor.scala
+++ b/akka-actors/src/main/scala/actor/Supervisor.scala
@@ -8,12 +8,9 @@ import se.scalablesolutions.akka.config.ScalaConfig._
 import se.scalablesolutions.akka.config.{ConfiguratorRepository, Configurator}
 import se.scalablesolutions.akka.util.Helpers._
 import se.scalablesolutions.akka.util.Logging
-import se.scalablesolutions.akka.dispatch.Dispatchers
 
 import java.util.concurrent.ConcurrentHashMap
 
-import scala.collection.mutable.HashMap
-   
 /**
  * Messages that the supervisor responds to and returns.
  *
@@ -34,42 +31,32 @@ case class OneForOneStrategy(maxNrOfRetries: Int, withinTimeRange: Int) extends
  * 

* Example usage: *

- *  class MySupervisorFactory extends SupervisorFactory {
- *
- *    override protected def getSupervisorConfig: SupervisorConfig = {
- *      SupervisorConfig(
- *        RestartStrategy(OneForOne, 3, 10),
- *        Supervise(
- *          myFirstActor,
- *          LifeCycle(Permanent))
- *        ::
- *        Supervise(
- *          mySecondActor,
- *          LifeCycle(Permanent))
- *        :: Nil)
- *    }
- * }
- * 
- * - * Then create a concrete factory in which we mix in support for the specific implementation of the Service we want to use. - * - *
- * object factory extends MySupervisorFactory
+ *  val factory = SupervisorFactory(
+ *    SupervisorConfig(
+ *      RestartStrategy(OneForOne, 3, 10),
+ *      Supervise(
+ *        myFirstActor,
+ *        LifeCycle(Permanent)) ::
+ *      Supervise(
+ *        mySecondActor,
+ *        LifeCycle(Permanent)) ::
+ *      Nil))
  * 
* * Then create a new Supervisor tree with the concrete Services we have defined. * *
- * val supervisor = factory.newSupervisor
- * supervisor ! Start // start up all managed servers
+ * val supervisor = factory.newInstance
+ * supervisor.start // start up all managed servers
  * 
* * @author Jonas Bonér */ -abstract class SupervisorFactory extends Logging { - def newSupervisor: Supervisor = newSupervisorFor(getSupervisorConfig) +class SupervisorFactory(val config: SupervisorConfig) extends Logging { - def newSupervisorFor(config: SupervisorConfig): Supervisor = config match { + def newInstance: Supervisor = newInstanceFor(config) + + def newInstanceFor(config: SupervisorConfig): Supervisor = config match { case SupervisorConfig(restartStrategy, _) => val supervisor = create(restartStrategy) supervisor.start @@ -77,12 +64,6 @@ abstract class SupervisorFactory extends Logging { supervisor } - /** - * To be overridden by concrete factory. - * Should return the SupervisorConfig for the supervisor. - */ - protected def getSupervisorConfig: SupervisorConfig - protected def create(strategy: RestartStrategy): Supervisor = strategy match { case RestartStrategy(scheme, maxNrOfRetries, timeRange) => scheme match { @@ -92,18 +73,24 @@ abstract class SupervisorFactory extends Logging { } } +object SupervisorFactory { + def apply(config: SupervisorConfig) = new SupervisorFactory(config) +} + /** * NOTE: *

- * The supervisor class is only used for the configuration system when configuring supervisor hierarchies declaratively. - * Should not be used in development. Instead wire the actors together using 'link', 'spawnLink' etc. and set the 'trapExit' - * flag in the actors that should trap error signals and trigger restart. + * The supervisor class is only used for the configuration system when configuring supervisor + * hierarchies declaratively. Should not be used as part of the regular programming API. Instead + * wire the actors together using 'link', 'spawnLink' etc. and set the 'trapExit' flag in the + * actors that should trap error signals and trigger restart. *

* See the ScalaDoc for the SupervisorFactory for an example on how to declaratively wire up actors. * * @author Jonas Bonér */ -class Supervisor private[akka] (handler: FaultHandlingStrategy) extends Actor with Logging with Configurator { +sealed class Supervisor private[akka] (handler: FaultHandlingStrategy) + extends Actor with Logging with Configurator { trapExit = List(classOf[Throwable]) faultHandler = Some(handler) //dispatcher = Dispatchers.newThreadBasedDispatcher(this) @@ -116,23 +103,29 @@ class Supervisor private[akka] (handler: FaultHandlingStrategy) extends Actor wi def isDefined(clazz: Class[_]): Boolean = actors.containsKey(clazz.getName) - def startSupervisor = { + override def start = { ConfiguratorRepository.registerConfigurator(this) actors.values.toArray.toList.foreach(println) - start + super[Actor].start this ! StartSupervisor } - def stopSupervisor = this ! StopSupervisor + def stop = this !? StopSupervisor - protected def receive: PartialFunction[Any, Unit] = { + protected def receive = { case StartSupervisor => - _linkedActors.toArray.toList.asInstanceOf[List[Actor]].foreach { actor => actor.start; log.info("Starting actor: %s", actor) } + _linkedActors.toArray.toList.asInstanceOf[List[Actor]].foreach { actor => + actor.start + log.info("Starting actor: %s", actor) + } case StopSupervisor => - _linkedActors.toArray.toList.asInstanceOf[List[Actor]].foreach { actor => actor.stop; log.info("Stopping actor: %s", actor) } + _linkedActors.toArray.toList.asInstanceOf[List[Actor]].foreach { actor => + actor.exit + log.info("Shutting actor down: %s", actor) + } log.info("Stopping supervisor: %s", this) - stop + exit } def configure(config: SupervisorConfig, factory: SupervisorFactory) = config match { @@ -145,7 +138,7 @@ class Supervisor private[akka] (handler: FaultHandlingStrategy) extends Actor wi startLink(actor) case SupervisorConfig(_, _) => // recursive configuration - val supervisor = factory.newSupervisorFor(server.asInstanceOf[SupervisorConfig]) + val supervisor = factory.newInstanceFor(server.asInstanceOf[SupervisorConfig]) supervisor ! StartSupervisor // FIXME what to do with recursively supervisors? }) diff --git a/akka-actors/src/main/scala/config/ActiveObjectGuiceConfigurator.scala b/akka-actors/src/main/scala/config/ActiveObjectGuiceConfigurator.scala index 2a0d454d22..04f90c331d 100644 --- a/akka-actors/src/main/scala/config/ActiveObjectGuiceConfigurator.scala +++ b/akka-actors/src/main/scala/config/ActiveObjectGuiceConfigurator.scala @@ -133,7 +133,7 @@ private[akka] class ActiveObjectGuiceConfigurator extends ActiveObjectConfigurat supervisor = Some(ActiveObject.supervise(restartStrategy, supervised)) //camelContext.addComponent(AKKA_CAMEL_ROUTING_SCHEME, new ActiveObjectComponent(this)) //camelContext.start - supervisor.get.startSupervisor + supervisor.get.start ConfiguratorRepository.registerConfigurator(this) this } diff --git a/akka-actors/src/test/scala/EventBasedSingleThreadActorTest.scala b/akka-actors/src/test/scala/EventBasedSingleThreadActorTest.scala index d8a3917293..fd9e20e95c 100644 --- a/akka-actors/src/test/scala/EventBasedSingleThreadActorTest.scala +++ b/akka-actors/src/test/scala/EventBasedSingleThreadActorTest.scala @@ -13,7 +13,7 @@ class EventBasedSingleThreadActorTest extends JUnitSuite { class TestActor extends Actor { dispatcher = Dispatchers.newEventBasedSingleThreadDispatcher(uuid) - def receive: PartialFunction[Any, Unit] = { + def receive = { case "Hello" => reply("World") case "Failure" => @@ -25,7 +25,7 @@ class EventBasedSingleThreadActorTest extends JUnitSuite { implicit val timeout = 5000L var oneWay = "nada" val actor = new Actor { - def receive: PartialFunction[Any, Unit] = { + def receive = { case "OneWay" => oneWay = "received" } } @@ -33,7 +33,7 @@ class EventBasedSingleThreadActorTest extends JUnitSuite { val result = actor ! "OneWay" Thread.sleep(100) assert("received" === oneWay) - actor.stop + actor.exit } @Test def shouldSendReplySync = { @@ -42,7 +42,7 @@ class EventBasedSingleThreadActorTest extends JUnitSuite { actor.start val result: String = actor !? "Hello" assert("World" === result) - actor.stop + actor.exit } @Test def shouldSendReplyAsync = { @@ -51,7 +51,7 @@ class EventBasedSingleThreadActorTest extends JUnitSuite { actor.start val result = actor !! "Hello" assert("World" === result.get.asInstanceOf[String]) - actor.stop + actor.exit } @Test def shouldSendReceiveException = { @@ -65,6 +65,6 @@ class EventBasedSingleThreadActorTest extends JUnitSuite { case e => assert("expected" === e.getMessage()) } - actor.stop + actor.exit } } diff --git a/akka-actors/src/test/scala/EventBasedSingleThreadDispatcherTest.scala b/akka-actors/src/test/scala/EventBasedSingleThreadDispatcherTest.scala index af62f475e0..2997c3b4f5 100644 --- a/akka-actors/src/test/scala/EventBasedSingleThreadDispatcherTest.scala +++ b/akka-actors/src/test/scala/EventBasedSingleThreadDispatcherTest.scala @@ -50,9 +50,9 @@ class EventBasedSingleThreadDispatcherTest extends JUnitSuite { internalTestMessagesDispatchedToHandlersAreExecutedInFIFOOrder } - val key1 = new Actor { def receive: PartialFunction[Any, Unit] = { case _ => {}} } - val key2 = new Actor { def receive: PartialFunction[Any, Unit] = { case _ => {}} } - val key3 = new Actor { def receive: PartialFunction[Any, Unit] = { case _ => {}} } + val key1 = new Actor { def receive = { case _ => {}} } + val key2 = new Actor { def receive = { case _ => {}} } + val key3 = new Actor { def receive = { case _ => {}} } private def internalTestMessagesDispatchedToTheSameHandlerAreExecutedSequentially: Unit = { val guardLock = new ReentrantLock diff --git a/akka-actors/src/test/scala/EventBasedThreadPoolActorTest.scala b/akka-actors/src/test/scala/EventBasedThreadPoolActorTest.scala index 168a20ff9c..b6747a9119 100644 --- a/akka-actors/src/test/scala/EventBasedThreadPoolActorTest.scala +++ b/akka-actors/src/test/scala/EventBasedThreadPoolActorTest.scala @@ -9,7 +9,7 @@ class EventBasedThreadPoolActorTest extends JUnitSuite { private val unit = TimeUnit.MILLISECONDS class TestActor extends Actor { - def receive: PartialFunction[Any, Unit] = { + def receive = { case "Hello" => reply("World") case "Failure" => @@ -21,7 +21,7 @@ class EventBasedThreadPoolActorTest extends JUnitSuite { implicit val timeout = 5000L var oneWay = "nada" val actor = new Actor { - def receive: PartialFunction[Any, Unit] = { + def receive = { case "OneWay" => oneWay = "received" } } @@ -29,7 +29,7 @@ class EventBasedThreadPoolActorTest extends JUnitSuite { val result = actor ! "OneWay" Thread.sleep(100) assert("received" === oneWay) - actor.stop + actor.exit } @Test def shouldSendReplySync = { @@ -38,7 +38,7 @@ class EventBasedThreadPoolActorTest extends JUnitSuite { actor.start val result: String = actor !? "Hello" assert("World" === result) - actor.stop + actor.exit } @Test def shouldSendReplyAsync = { @@ -47,7 +47,7 @@ class EventBasedThreadPoolActorTest extends JUnitSuite { actor.start val result = actor !! "Hello" assert("World" === result.get.asInstanceOf[String]) - actor.stop + actor.exit } @Test def shouldSendReceiveException = { @@ -61,6 +61,6 @@ class EventBasedThreadPoolActorTest extends JUnitSuite { case e => assert("expected" === e.getMessage()) } - actor.stop + actor.exit } } diff --git a/akka-actors/src/test/scala/EventBasedThreadPoolDispatcherTest.scala b/akka-actors/src/test/scala/EventBasedThreadPoolDispatcherTest.scala index 7391c348d9..84d778a39d 100644 --- a/akka-actors/src/test/scala/EventBasedThreadPoolDispatcherTest.scala +++ b/akka-actors/src/test/scala/EventBasedThreadPoolDispatcherTest.scala @@ -13,9 +13,9 @@ import se.scalablesolutions.akka.actor.Actor class EventBasedThreadPoolDispatcherTest extends JUnitSuite { private var threadingIssueDetected: AtomicBoolean = null - val key1 = new Actor { def receive: PartialFunction[Any, Unit] = { case _ => {}} } - val key2 = new Actor { def receive: PartialFunction[Any, Unit] = { case _ => {}} } - val key3 = new Actor { def receive: PartialFunction[Any, Unit] = { case _ => {}} } + val key1 = new Actor { def receive = { case _ => {}} } + val key2 = new Actor { def receive = { case _ => {}} } + val key3 = new Actor { def receive = { case _ => {}} } @Before def setUp = { diff --git a/akka-actors/src/test/scala/InMemoryActorTest.scala b/akka-actors/src/test/scala/InMemoryActorTest.scala index 83c105d69f..cd06b80d0a 100644 --- a/akka-actors/src/test/scala/InMemoryActorTest.scala +++ b/akka-actors/src/test/scala/InMemoryActorTest.scala @@ -30,7 +30,7 @@ class InMemStatefulActor extends Actor { private lazy val vectorState = TransactionalState.newVector[String] private lazy val refState = TransactionalState.newRef[String] - def receive: PartialFunction[Any, Unit] = { + def receive = { case GetMapState(key) => reply(mapState.get(key).get) case GetVectorSize => @@ -79,7 +79,7 @@ class InMemStatefulActor extends Actor { @serializable class InMemFailerActor extends Actor { makeTransactionRequired - def receive: PartialFunction[Any, Unit] = { + def receive = { case "Failure" => throw new RuntimeException("expected") } diff --git a/akka-actors/src/test/scala/RemoteActorTest.scala b/akka-actors/src/test/scala/RemoteActorTest.scala index a187c3f16a..447ada87f6 100644 --- a/akka-actors/src/test/scala/RemoteActorTest.scala +++ b/akka-actors/src/test/scala/RemoteActorTest.scala @@ -11,14 +11,14 @@ object Global { var oneWay = "nada" } class RemoteActorSpecActorUnidirectional extends Actor { - def receive: PartialFunction[Any, Unit] = { + def receive = { case "OneWay" => Global.oneWay = "received" } } class RemoteActorSpecActorBidirectional extends Actor { - def receive: PartialFunction[Any, Unit] = { + def receive = { case "Hello" => reply("World") case "Failure" => @@ -46,7 +46,7 @@ class RemoteActorTest extends JUnitSuite { val result = actor ! "OneWay" Thread.sleep(100) assert("received" === Global.oneWay) - actor.stop + actor.exit } @Test @@ -57,7 +57,7 @@ class RemoteActorTest extends JUnitSuite { actor.start val result: String = actor !? "Hello" assert("World" === result) - actor.stop + actor.exit } @Test @@ -68,7 +68,7 @@ class RemoteActorTest extends JUnitSuite { actor.start val result = actor !! "Hello" assert("World" === result.get.asInstanceOf[String]) - actor.stop + actor.exit } @Test @@ -84,6 +84,6 @@ class RemoteActorTest extends JUnitSuite { case e => assert("expected" === e.getMessage()) } - actor.stop + actor.exit } } diff --git a/akka-actors/src/test/scala/RemoteSupervisorTest.scala b/akka-actors/src/test/scala/RemoteSupervisorTest.scala index 5aefa0d0a1..2150707fac 100644 --- a/akka-actors/src/test/scala/RemoteSupervisorTest.scala +++ b/akka-actors/src/test/scala/RemoteSupervisorTest.scala @@ -13,18 +13,18 @@ import org.junit.Test object Log { var messageLog: String = "" - var oneWayLog: String = "" + var oneWayLog: String = "" } + /** * @author Jonas Bonér */ -class RemoteSupervisorTest extends JUnitSuite { - +class RemoteSupervisorTest extends JUnitSuite { akka.Config.config new Thread(new Runnable() { - def run = { - RemoteServer.start - } + def run = { + RemoteServer.start + } }).start Thread.sleep(1000) @@ -277,166 +277,166 @@ class RemoteSupervisorTest extends JUnitSuite { } } */ - + /* - @Test def shouldOneWayKillSingleActorAllForOne = { - Logg.messageLog = "" - val sup = getSingleActorAllForOneSupervisor - sup ! StartSupervisor - Thread.sleep(500) - intercept[RuntimeException] { - pingpong1 ! BinaryString("Die") - } - Thread.sleep(500) - expect("DIE") { - Logg.messageLog - } - } + @Test def shouldOneWayKillSingleActorAllForOne = { + Logg.messageLog = "" + val sup = getSingleActorAllForOneSupervisor + sup ! StartSupervisor + Thread.sleep(500) + intercept[RuntimeException] { + pingpong1 ! BinaryString("Die") + } + Thread.sleep(500) + expect("DIE") { + Logg.messageLog + } + } - @Test def shouldOneWayCallKillCallSingleActorAllForOne = { - Logg.messageLog = "" - val sup = getSingleActorAllForOneSupervisor - sup ! StartSupervisor - Thread.sleep(500) - expect("pong") { - (pingpong1 ! BinaryString("Ping")).getOrElse("nil") - } - Thread.sleep(500) - expect("ping") { - Logg.messageLog - } - intercept[RuntimeException] { - pingpong1 ! BinaryString("Die") - } - Thread.sleep(500) - expect("pingDIE") { - Logg.messageLog - } - expect("pong") { - (pingpong1 ! BinaryString("Ping")).getOrElse("nil") - } - Thread.sleep(500) - expect("pingDIEping") { - Logg.messageLog - } - } + @Test def shouldOneWayCallKillCallSingleActorAllForOne = { + Logg.messageLog = "" + val sup = getSingleActorAllForOneSupervisor + sup ! StartSupervisor + Thread.sleep(500) + expect("pong") { + (pingpong1 ! BinaryString("Ping")).getOrElse("nil") + } + Thread.sleep(500) + expect("ping") { + Logg.messageLog + } + intercept[RuntimeException] { + pingpong1 ! BinaryString("Die") + } + Thread.sleep(500) + expect("pingDIE") { + Logg.messageLog + } + expect("pong") { + (pingpong1 ! BinaryString("Ping")).getOrElse("nil") + } + Thread.sleep(500) + expect("pingDIEping") { + Logg.messageLog + } + } - @Test def shouldOneWayKillMultipleActorsOneForOne = { - Logg.messageLog = "" - val sup = getMultipleActorsOneForOneConf - sup ! StartSupervisor - Thread.sleep(500) - intercept[RuntimeException] { - pingpong3 ! BinaryString("Die") - } - Thread.sleep(500) - expect("DIE") { - Logg.messageLog - } - } + @Test def shouldOneWayKillMultipleActorsOneForOne = { + Logg.messageLog = "" + val sup = getMultipleActorsOneForOneConf + sup ! StartSupervisor + Thread.sleep(500) + intercept[RuntimeException] { + pingpong3 ! BinaryString("Die") + } + Thread.sleep(500) + expect("DIE") { + Logg.messageLog + } + } - def tesOneWayCallKillCallMultipleActorsOneForOne = { - Logg.messageLog = "" - val sup = getMultipleActorsOneForOneConf - sup ! StartSupervisor - Thread.sleep(500) - expect("pong") { - (pingpong1 ! BinaryString("Ping")).getOrElse("nil") - } - Thread.sleep(500) - expect("pong") { - (pingpong2 ! BinaryString("Ping")).getOrElse("nil") - } - Thread.sleep(500) - expect("pong") { - (pingpong3 ! BinaryString("Ping")).getOrElse("nil") - } - Thread.sleep(500) - expect("pingpingping") { - Logg.messageLog - } - intercept[RuntimeException] { - pingpong2 ! BinaryString("Die") - } - Thread.sleep(500) - expect("pingpingpingDIE") { - Logg.messageLog - } - expect("pong") { - (pingpong1 ! BinaryString("Ping")).getOrElse("nil") - } - Thread.sleep(500) - expect("pong") { - (pingpong2 ! BinaryString("Ping")).getOrElse("nil") - } - Thread.sleep(500) - expect("pong") { - (pingpong3 ! BinaryString("Ping")).getOrElse("nil") - } - Thread.sleep(500) - expect("pingpingpingDIEpingpingping") { - Logg.messageLog - } - } + def tesOneWayCallKillCallMultipleActorsOneForOne = { + Logg.messageLog = "" + val sup = getMultipleActorsOneForOneConf + sup ! StartSupervisor + Thread.sleep(500) + expect("pong") { + (pingpong1 ! BinaryString("Ping")).getOrElse("nil") + } + Thread.sleep(500) + expect("pong") { + (pingpong2 ! BinaryString("Ping")).getOrElse("nil") + } + Thread.sleep(500) + expect("pong") { + (pingpong3 ! BinaryString("Ping")).getOrElse("nil") + } + Thread.sleep(500) + expect("pingpingping") { + Logg.messageLog + } + intercept[RuntimeException] { + pingpong2 ! BinaryString("Die") + } + Thread.sleep(500) + expect("pingpingpingDIE") { + Logg.messageLog + } + expect("pong") { + (pingpong1 ! BinaryString("Ping")).getOrElse("nil") + } + Thread.sleep(500) + expect("pong") { + (pingpong2 ! BinaryString("Ping")).getOrElse("nil") + } + Thread.sleep(500) + expect("pong") { + (pingpong3 ! BinaryString("Ping")).getOrElse("nil") + } + Thread.sleep(500) + expect("pingpingpingDIEpingpingping") { + Logg.messageLog + } + } - @Test def shouldOneWayKillMultipleActorsAllForOne = { - Logg.messageLog = "" - val sup = getMultipleActorsAllForOneConf - sup ! StartSupervisor - Thread.sleep(500) - intercept[RuntimeException] { - pingpong2 ! BinaryString("Die") - } - Thread.sleep(500) - expect("DIEDIEDIE") { - Logg.messageLog - } - } + @Test def shouldOneWayKillMultipleActorsAllForOne = { + Logg.messageLog = "" + val sup = getMultipleActorsAllForOneConf + sup ! StartSupervisor + Thread.sleep(500) + intercept[RuntimeException] { + pingpong2 ! BinaryString("Die") + } + Thread.sleep(500) + expect("DIEDIEDIE") { + Logg.messageLog + } + } - def tesOneWayCallKillCallMultipleActorsAllForOne = { - Logg.messageLog = "" - val sup = getMultipleActorsAllForOneConf - sup ! StartSupervisor - Thread.sleep(500) - expect("pong") { - pingpong1 ! BinaryString("Ping") - } - Thread.sleep(500) - expect("pong") { - (pingpong2 ! BinaryString("Ping")).getOrElse("nil") - } - Thread.sleep(500) - expect("pong") { - (pingpong3 ! BinaryString("Ping")).getOrElse("nil") - } - Thread.sleep(500) - expect("pingpingping") { - Logg.messageLog - } - intercept[RuntimeException] { - pingpong2 ! BinaryString("Die") - } - Thread.sleep(500) - expect("pingpingpingDIEDIEDIE") { - Logg.messageLog - } - expect("pong") { - (pingpong1 ! BinaryString("Ping")).getOrElse("nil") - } - Thread.sleep(500) - expect("pong") { - (pingpong2 ! BinaryString("Ping")).getOrElse("nil") - } - Thread.sleep(500) - expect("pong") { - (pingpong3 ! BinaryString("Ping")).getOrElse("nil") - } - Thread.sleep(500) - expect("pingpingpingDIEDIEDIEpingpingping") { - Logg.messageLog - } - } - */ + def tesOneWayCallKillCallMultipleActorsAllForOne = { + Logg.messageLog = "" + val sup = getMultipleActorsAllForOneConf + sup ! StartSupervisor + Thread.sleep(500) + expect("pong") { + pingpong1 ! BinaryString("Ping") + } + Thread.sleep(500) + expect("pong") { + (pingpong2 ! BinaryString("Ping")).getOrElse("nil") + } + Thread.sleep(500) + expect("pong") { + (pingpong3 ! BinaryString("Ping")).getOrElse("nil") + } + Thread.sleep(500) + expect("pingpingping") { + Logg.messageLog + } + intercept[RuntimeException] { + pingpong2 ! BinaryString("Die") + } + Thread.sleep(500) + expect("pingpingpingDIEDIEDIE") { + Logg.messageLog + } + expect("pong") { + (pingpong1 ! BinaryString("Ping")).getOrElse("nil") + } + Thread.sleep(500) + expect("pong") { + (pingpong2 ! BinaryString("Ping")).getOrElse("nil") + } + Thread.sleep(500) + expect("pong") { + (pingpong3 ! BinaryString("Ping")).getOrElse("nil") + } + Thread.sleep(500) + expect("pingpingpingDIEDIEDIEpingpingping") { + Logg.messageLog + } + } + */ /* @Test def shouldNestedSupervisorsTerminateFirstLevelActorAllForOne = { @@ -467,34 +467,29 @@ class RemoteSupervisorTest extends JUnitSuite { pingpong1 = new RemotePingPong1Actor pingpong1.makeRemote(RemoteServer.HOSTNAME, RemoteServer.PORT) - object factory extends SupervisorFactory { - override def getSupervisorConfig: SupervisorConfig = { - SupervisorConfig( - RestartStrategy(AllForOne, 3, 100), - Supervise( - pingpong1, - LifeCycle(Permanent)) - :: Nil) - } - } - factory.newSupervisor + val factory = SupervisorFactory( + SupervisorConfig( + RestartStrategy(AllForOne, 3, 100), + Supervise( + pingpong1, + LifeCycle(Permanent)) + :: Nil)) + + factory.newInstance } def getSingleActorOneForOneSupervisor: Supervisor = { pingpong1 = new RemotePingPong1Actor pingpong1.makeRemote(RemoteServer.HOSTNAME, RemoteServer.PORT) - object factory extends SupervisorFactory { - override def getSupervisorConfig: SupervisorConfig = { - SupervisorConfig( - RestartStrategy(OneForOne, 3, 100), - Supervise( - pingpong1, - LifeCycle(Permanent)) - :: Nil) - } - } - factory.newSupervisor + val factory = SupervisorFactory( + SupervisorConfig( + RestartStrategy(OneForOne, 3, 100), + Supervise( + pingpong1, + LifeCycle(Permanent)) + :: Nil)) + factory.newInstance } def getMultipleActorsAllForOneConf: Supervisor = { @@ -505,25 +500,22 @@ class RemoteSupervisorTest extends JUnitSuite { pingpong3 = new RemotePingPong3Actor pingpong3.makeRemote(RemoteServer.HOSTNAME, RemoteServer.PORT) - object factory extends SupervisorFactory { - override def getSupervisorConfig: SupervisorConfig = { - SupervisorConfig( - RestartStrategy(AllForOne, 3, 100), - Supervise( - pingpong1, - LifeCycle(Permanent)) - :: - Supervise( - pingpong2, - LifeCycle(Permanent)) - :: - Supervise( - pingpong3, - LifeCycle(Permanent)) - :: Nil) - } - } - factory.newSupervisor + val factory = SupervisorFactory( + SupervisorConfig( + RestartStrategy(AllForOne, 3, 100), + Supervise( + pingpong1, + LifeCycle(Permanent)) + :: + Supervise( + pingpong2, + LifeCycle(Permanent)) + :: + Supervise( + pingpong3, + LifeCycle(Permanent)) + :: Nil)) + factory.newInstance } def getMultipleActorsOneForOneConf: Supervisor = { @@ -534,25 +526,22 @@ class RemoteSupervisorTest extends JUnitSuite { pingpong3 = new RemotePingPong3Actor pingpong3.makeRemote(RemoteServer.HOSTNAME, RemoteServer.PORT) - object factory extends SupervisorFactory { - override def getSupervisorConfig: SupervisorConfig = { - SupervisorConfig( - RestartStrategy(OneForOne, 3, 100), - Supervise( - pingpong1, - LifeCycle(Permanent)) - :: - Supervise( - pingpong2, - LifeCycle(Permanent)) - :: - Supervise( - pingpong3, - LifeCycle(Permanent)) - :: Nil) - } - } - factory.newSupervisor + val factory = SupervisorFactory( + SupervisorConfig( + RestartStrategy(OneForOne, 3, 100), + Supervise( + pingpong1, + LifeCycle(Permanent)) + :: + Supervise( + pingpong2, + LifeCycle(Permanent)) + :: + Supervise( + pingpong3, + LifeCycle(Permanent)) + :: Nil)) + factory.newInstance } def getNestedSupervisorsAllForOneConf: Supervisor = { @@ -563,34 +552,30 @@ class RemoteSupervisorTest extends JUnitSuite { pingpong3 = new RemotePingPong3Actor pingpong3.makeRemote(RemoteServer.HOSTNAME, RemoteServer.PORT) - object factory extends SupervisorFactory { - override def getSupervisorConfig: SupervisorConfig = { - SupervisorConfig( - RestartStrategy(AllForOne, 3, 100), - Supervise( - pingpong1, - LifeCycle(Permanent)) - :: - SupervisorConfig( - RestartStrategy(AllForOne, 3, 100), - Supervise( - pingpong2, - LifeCycle(Permanent)) + val factory = SupervisorFactory( + SupervisorConfig( + RestartStrategy(AllForOne, 3, 100), + Supervise( + pingpong1, + LifeCycle(Permanent)) :: - Supervise( - pingpong3, - LifeCycle(Permanent)) - :: Nil) - :: Nil) - } - } - factory.newSupervisor - } - + SupervisorConfig( + RestartStrategy(AllForOne, 3, 100), + Supervise( + pingpong2, + LifeCycle(Permanent)) + :: + Supervise( + pingpong3, + LifeCycle(Permanent)) + :: Nil) + :: Nil)) + factory.newInstance + } } @serializable class RemotePingPong1Actor extends Actor { - override def receive: PartialFunction[Any, Unit] = { + def receive = { case BinaryString("Ping") => Log.messageLog += "ping" reply("pong") @@ -601,26 +586,28 @@ class RemoteSupervisorTest extends JUnitSuite { case BinaryString("Die") => throw new RuntimeException("DIE") } + override protected def postRestart(reason: AnyRef, config: Option[AnyRef]) { Log.messageLog += reason.asInstanceOf[Exception].getMessage } } @serializable class RemotePingPong2Actor extends Actor { - override def receive: PartialFunction[Any, Unit] = { + def receive = { case BinaryString("Ping") => Log.messageLog += "ping" reply("pong") case BinaryString("Die") => throw new RuntimeException("DIE") } + override protected def postRestart(reason: AnyRef, config: Option[AnyRef]) { Log.messageLog += reason.asInstanceOf[Exception].getMessage } } @serializable class RemotePingPong3Actor extends Actor { - override def receive: PartialFunction[Any, Unit] = { + def receive = { case BinaryString("Ping") => Log.messageLog += "ping" reply("pong") diff --git a/akka-actors/src/test/scala/SchedulerTest.scala b/akka-actors/src/test/scala/SchedulerTest.scala index 029872a295..389fba7012 100644 --- a/akka-actors/src/test/scala/SchedulerTest.scala +++ b/akka-actors/src/test/scala/SchedulerTest.scala @@ -11,7 +11,7 @@ class SchedulerTest extends JUnitSuite { var count = 0 case object Tick val actor = new Actor() { - def receive: PartialFunction[Any, Unit] = { + def receive = { case Tick => count += 1 }} actor.start diff --git a/akka-actors/src/test/scala/SupervisorTest.scala b/akka-actors/src/test/scala/SupervisorTest.scala index 7bba332e69..f2a98727d6 100644 --- a/akka-actors/src/test/scala/SupervisorTest.scala +++ b/akka-actors/src/test/scala/SupervisorTest.scala @@ -4,7 +4,7 @@ package se.scalablesolutions.akka.actor -import config.ScalaConfig._ +import se.scalablesolutions.akka.config.ScalaConfig._ import org.scalatest.junit.JUnitSuite import org.junit.Test @@ -453,33 +453,27 @@ class SupervisorTest extends JUnitSuite { pingpong1 = new PingPong1Actor - object factory extends SupervisorFactory { - override def getSupervisorConfig: SupervisorConfig = { + val factory = SupervisorFactory( SupervisorConfig( RestartStrategy(AllForOne, 3, 100), Supervise( pingpong1, LifeCycle(Permanent)) - :: Nil) - } - } - factory.newSupervisor + :: Nil)) + factory.newInstance } def getSingleActorOneForOneSupervisor: Supervisor = { pingpong1 = new PingPong1Actor - object factory extends SupervisorFactory { - override def getSupervisorConfig: SupervisorConfig = { + val factory = SupervisorFactory( SupervisorConfig( RestartStrategy(OneForOne, 3, 100), Supervise( pingpong1, LifeCycle(Permanent)) - :: Nil) - } - } - factory.newSupervisor + :: Nil)) + factory.newInstance } def getMultipleActorsAllForOneConf: Supervisor = { @@ -487,8 +481,7 @@ class SupervisorTest extends JUnitSuite { pingpong2 = new PingPong2Actor pingpong3 = new PingPong3Actor - object factory extends SupervisorFactory { - override def getSupervisorConfig: SupervisorConfig = { + val factory = SupervisorFactory( SupervisorConfig( RestartStrategy(AllForOne, 3, 100), Supervise( @@ -502,10 +495,8 @@ class SupervisorTest extends JUnitSuite { Supervise( pingpong3, LifeCycle(Permanent)) - :: Nil) - } - } - factory.newSupervisor + :: Nil)) + factory.newInstance } def getMultipleActorsOneForOneConf: Supervisor = { @@ -513,8 +504,7 @@ class SupervisorTest extends JUnitSuite { pingpong2 = new PingPong2Actor pingpong3 = new PingPong3Actor - object factory extends SupervisorFactory { - override def getSupervisorConfig: SupervisorConfig = { + val factory = SupervisorFactory( SupervisorConfig( RestartStrategy(OneForOne, 3, 100), Supervise( @@ -528,10 +518,8 @@ class SupervisorTest extends JUnitSuite { Supervise( pingpong3, LifeCycle(Permanent)) - :: Nil) - } - } - factory.newSupervisor + :: Nil)) + factory.newInstance } def getNestedSupervisorsAllForOneConf: Supervisor = { @@ -539,8 +527,7 @@ class SupervisorTest extends JUnitSuite { pingpong2 = new PingPong2Actor pingpong3 = new PingPong3Actor - object factory extends SupervisorFactory { - override def getSupervisorConfig: SupervisorConfig = { + val factory = SupervisorFactory( SupervisorConfig( RestartStrategy(AllForOne, 3, 100), Supervise( @@ -557,14 +544,12 @@ class SupervisorTest extends JUnitSuite { pingpong3, LifeCycle(Permanent)) :: Nil) - :: Nil) - } - } - factory.newSupervisor + :: Nil)) + factory.newInstance } class PingPong1Actor extends Actor { - override def receive: PartialFunction[Any, Unit] = { + def receive = { case Ping => messageLog += "ping" reply("pong") @@ -581,7 +566,7 @@ class SupervisorTest extends JUnitSuite { } class PingPong2Actor extends Actor { - override def receive: PartialFunction[Any, Unit] = { + def receive = { case Ping => messageLog += "ping" reply("pong") @@ -594,7 +579,7 @@ class SupervisorTest extends JUnitSuite { } class PingPong3Actor extends Actor { - override def receive: PartialFunction[Any, Unit] = { + def receive = { case Ping => messageLog += "ping" reply("pong") diff --git a/akka-actors/src/test/scala/ThreadBasedActorTest.scala b/akka-actors/src/test/scala/ThreadBasedActorTest.scala index 6d30ec58db..56762a7321 100644 --- a/akka-actors/src/test/scala/ThreadBasedActorTest.scala +++ b/akka-actors/src/test/scala/ThreadBasedActorTest.scala @@ -13,7 +13,7 @@ class ThreadBasedActorTest extends JUnitSuite { class TestActor extends Actor { dispatcher = Dispatchers.newThreadBasedDispatcher(this) - def receive: PartialFunction[Any, Unit] = { + def receive = { case "Hello" => reply("World") case "Failure" => @@ -25,7 +25,7 @@ class ThreadBasedActorTest extends JUnitSuite { implicit val timeout = 5000L var oneWay = "nada" val actor = new Actor { - def receive: PartialFunction[Any, Unit] = { + def receive = { case "OneWay" => oneWay = "received" } } @@ -33,7 +33,7 @@ class ThreadBasedActorTest extends JUnitSuite { val result = actor ! "OneWay" Thread.sleep(100) assert("received" === oneWay) - actor.stop + actor.exit } @Test def shouldSendReplySync = { @@ -42,7 +42,7 @@ class ThreadBasedActorTest extends JUnitSuite { actor.start val result: String = actor !? "Hello" assert("World" === result) - actor.stop + actor.exit } @Test def shouldSendReplyAsync = { @@ -51,7 +51,7 @@ class ThreadBasedActorTest extends JUnitSuite { actor.start val result = actor !! "Hello" assert("World" === result.get.asInstanceOf[String]) - actor.stop + actor.exit } @Test def shouldSendReceiveException = { @@ -65,6 +65,6 @@ class ThreadBasedActorTest extends JUnitSuite { case e => assert("expected" === e.getMessage()) } - actor.stop + actor.exit } } diff --git a/akka-actors/src/test/scala/ThreadBasedDispatcherTest.scala b/akka-actors/src/test/scala/ThreadBasedDispatcherTest.scala index e5f4a6f1d4..1495257a7f 100644 --- a/akka-actors/src/test/scala/ThreadBasedDispatcherTest.scala +++ b/akka-actors/src/test/scala/ThreadBasedDispatcherTest.scala @@ -13,9 +13,9 @@ import se.scalablesolutions.akka.actor.Actor class ThreadBasedDispatcherTest extends JUnitSuite { private var threadingIssueDetected: AtomicBoolean = null - val key1 = new Actor { def receive: PartialFunction[Any, Unit] = { case _ => {}} } - val key2 = new Actor { def receive: PartialFunction[Any, Unit] = { case _ => {}} } - val key3 = new Actor { def receive: PartialFunction[Any, Unit] = { case _ => {}} } + val key1 = new Actor { def receive = { case _ => {}} } + val key2 = new Actor { def receive = { case _ => {}} } + val key3 = new Actor { def receive = { case _ => {}} } class TestMessageHandle(handleLatch: CountDownLatch) extends MessageInvoker { val guardLock: Lock = new ReentrantLock diff --git a/akka-amqp/src/main/scala/AMQP.scala b/akka-amqp/src/main/scala/AMQP.scala index 6dddd7a377..0c2376a905 100644 --- a/akka-amqp/src/main/scala/AMQP.scala +++ b/akka-amqp/src/main/scala/AMQP.scala @@ -32,7 +32,7 @@ import java.io.IOException * val consumer = AMQP.newConsumer(params, hostname, port, exchange, ExchangeType.Direct, Serializer.ScalaJSON, None, 100) * * consumer ! MessageConsumerListener(queue, routingKey, new Actor() { - * def receive: PartialFunction[Any, Unit] = { + * def receive = { * case Message(payload, _, _, _, _) => log.debug("Received message: %s", payload) * } * }) @@ -208,7 +208,7 @@ object AMQP extends Actor { override def shutdown = { connections.values.asScala.foreach(_ ! Stop) - stop + exit } /** @@ -236,7 +236,7 @@ object AMQP extends Actor { channel.basicPublish(exchangeName, routingKey, mandatory, immediate, properties, payload.asInstanceOf[Array[Byte]]) case Stop => disconnect - stop + exit } protected def setupChannel = { @@ -323,7 +323,7 @@ object AMQP extends Actor { case Stop => listeners.elements.toList.map(_._2).foreach(unregisterListener(_)) disconnect - stop + exit case message: Message => handleIllegalMessage("AMQP.Consumer [" + this + "] can't be used to send messages, ignoring message [" + message + "]") @@ -401,7 +401,7 @@ object AMQP extends Actor { case Some(tag) => channel.basicCancel(tag) unlink(listener.actor) - listener.actor.stop + listener.actor.exit log.debug("Message consumer is cancelled and shut down [%s]", listener) } } diff --git a/akka-amqp/src/main/scala/ExampleSession.scala b/akka-amqp/src/main/scala/ExampleSession.scala index 3054080b8f..574b825470 100644 --- a/akka-amqp/src/main/scala/ExampleSession.scala +++ b/akka-amqp/src/main/scala/ExampleSession.scala @@ -30,7 +30,7 @@ object ExampleSession { def direct = { val consumer = AMQP.newConsumer(CONFIG, HOSTNAME, PORT, IM, ExchangeType.Direct, None, 100, false, false, Map[String, AnyRef]()) consumer ! MessageConsumerListener("@george_bush", "direct", new Actor() { - def receive: PartialFunction[Any, Unit] = { + def receive = { case Message(payload, _, _, _, _) => log.info("@george_bush received message from: %s", new String(payload.asInstanceOf[Array[Byte]])) } }) @@ -41,12 +41,12 @@ object ExampleSession { def fanout = { val consumer = AMQP.newConsumer(CONFIG, HOSTNAME, PORT, CHAT, ExchangeType.Fanout, None, 100, false, false, Map[String, AnyRef]()) consumer ! MessageConsumerListener("@george_bush", "", new Actor() { - def receive: PartialFunction[Any, Unit] = { + def receive = { case Message(payload, _, _, _, _) => log.info("@george_bush received message from: %s", new String(payload.asInstanceOf[Array[Byte]])) } }) consumer ! MessageConsumerListener("@barack_obama", "", new Actor() { - def receive: PartialFunction[Any, Unit] = { + def receive = { case Message(payload, _, _, _, _) => log.info("@barack_obama received message from: %s", new String(payload.asInstanceOf[Array[Byte]])) } }) diff --git a/akka-fun-test-java/src/test/java/se/scalablesolutions/akka/api/InMemNestedStateTest.java b/akka-fun-test-java/src/test/java/se/scalablesolutions/akka/api/InMemNestedStateTest.java index 1d70324a1a..26c6747eca 100644 --- a/akka-fun-test-java/src/test/java/se/scalablesolutions/akka/api/InMemNestedStateTest.java +++ b/akka-fun-test-java/src/test/java/se/scalablesolutions/akka/api/InMemNestedStateTest.java @@ -17,7 +17,7 @@ public class InMemNestedStateTest extends TestCase { final private ActiveObjectConfigurator conf = new ActiveObjectConfigurator(); - protected void setUp() { + public InMemNestedStateTest() { conf.configure( new RestartStrategy(new AllForOne(), 3, 5000), new Component[]{ @@ -26,7 +26,7 @@ public class InMemNestedStateTest extends TestCase { new Component(InMemStatefulNested.class, new LifeCycle(new Permanent()), 10000000), new Component(InMemFailer.class, new LifeCycle(new Permanent()), 1000) //new Component("inmem-clasher", InMemClasher.class, InMemClasherImpl.class, new LifeCycle(new Permanent()), 100000) - }).inject().supervise(); + }).supervise(); Config.config(); InMemStateful stateful = conf.getInstance(InMemStateful.class); stateful.init(); @@ -34,10 +34,6 @@ public class InMemNestedStateTest extends TestCase { nested.init(); } - protected void tearDown() { - conf.stop(); - } - public void testMapShouldNotRollbackStateForStatefulServerInCaseOfSuccess() throws Exception { InMemStateful stateful = conf.getInstance(InMemStateful.class); stateful.setMapState("testShouldNotRollbackStateForStatefulServerInCaseOfSuccess", "init"); // set init state diff --git a/akka-fun-test-java/src/test/java/se/scalablesolutions/akka/api/InMemoryStateTest.java b/akka-fun-test-java/src/test/java/se/scalablesolutions/akka/api/InMemoryStateTest.java index 3dbe92ca75..e29e8ef81f 100644 --- a/akka-fun-test-java/src/test/java/se/scalablesolutions/akka/api/InMemoryStateTest.java +++ b/akka-fun-test-java/src/test/java/se/scalablesolutions/akka/api/InMemoryStateTest.java @@ -9,7 +9,9 @@ import junit.framework.TestCase; import se.scalablesolutions.akka.Config; import se.scalablesolutions.akka.config.*; import se.scalablesolutions.akka.config.ActiveObjectConfigurator; + import static se.scalablesolutions.akka.config.JavaConfig.*; + import se.scalablesolutions.akka.actor.*; import se.scalablesolutions.akka.Kernel; @@ -18,27 +20,23 @@ public class InMemoryStateTest extends TestCase { final private ActiveObjectConfigurator conf = new ActiveObjectConfigurator(); - protected void setUp() { + public InMemoryStateTest() { Config.config(); conf.configure( new RestartStrategy(new AllForOne(), 3, 5000), new Component[]{ new Component(InMemStateful.class, new LifeCycle(new Permanent()), - //new RestartCallbacks("preRestart", "postRestart")), - 10000), + //new RestartCallbacks("preRestart", "postRestart")), + 10000), new Component(InMemFailer.class, new LifeCycle(new Permanent()), - 10000) - }).inject().supervise(); - InMemStateful stateful = conf.getInstance(InMemStateful.class); - stateful.init(); + 10000) + }).supervise(); + InMemStateful stateful = conf.getInstance(InMemStateful.class); + stateful.init(); } - protected void tearDown() { - conf.stop(); - } - public void testMapShouldNotRollbackStateForStatefulServerInCaseOfSuccess() { InMemStateful stateful = conf.getInstance(InMemStateful.class); stateful.setMapState("testShouldNotRollbackStateForStatefulServerInCaseOfSuccess", "init"); // set init state diff --git a/akka-persistence/src/test/scala/CassandraPersistentActorSpec.scala b/akka-persistence/src/test/scala/CassandraPersistentActorSpec.scala index 28fe92651b..305763eba3 100644 --- a/akka-persistence/src/test/scala/CassandraPersistentActorSpec.scala +++ b/akka-persistence/src/test/scala/CassandraPersistentActorSpec.scala @@ -35,7 +35,7 @@ class CassandraPersistentActor extends Actor { private lazy val vectorState: PersistentVector = PersistentState.newVector(CassandraStorageConfig()) private lazy val refState: PersistentRef = PersistentState.newRef(CassandraStorageConfig()) - def receive: PartialFunction[Any, Unit] = { + def receive = { case GetMapState(key) => reply(mapState.get(key).get) case GetVectorSize => @@ -67,7 +67,7 @@ class CassandraPersistentActor extends Actor { @serializable class PersistentFailerActor extends Actor { makeTransactionRequired - def receive: PartialFunction[Any, Unit] = { + def receive = { case "Failure" => throw new RuntimeException("expected") } diff --git a/akka-persistence/src/test/scala/MongoPersistentActorSpec.scala b/akka-persistence/src/test/scala/MongoPersistentActorSpec.scala index 4fc18e8967..b04b2d04b4 100644 --- a/akka-persistence/src/test/scala/MongoPersistentActorSpec.scala +++ b/akka-persistence/src/test/scala/MongoPersistentActorSpec.scala @@ -32,7 +32,7 @@ class BankAccountActor extends Actor { private lazy val accountState: PersistentMap = PersistentState.newMap(MongoStorageConfig()) private lazy val txnLog: PersistentVector = PersistentState.newVector(MongoStorageConfig()) - def receive: PartialFunction[Any, Unit] = { + def receive = { // check balance case Balance(accountNo) => txnLog.add("Balance:" + accountNo) @@ -176,7 +176,7 @@ class BankAccountActor extends Actor { txnLog = PersistentState.newVector(MongoStorageConfig()) } - def receive: PartialFunction[Any, Unit] = { + def receive = { // check balance case Balance(accountNo) => txnLog.add("Balance:" + accountNo) diff --git a/akka-samples-lift/src/main/scala/akka/SimpleService.scala b/akka-samples-lift/src/main/scala/akka/SimpleService.scala index 8f7537f5bf..b4bbd52157 100644 --- a/akka-samples-lift/src/main/scala/akka/SimpleService.scala +++ b/akka-samples-lift/src/main/scala/akka/SimpleService.scala @@ -29,7 +29,7 @@ class SimpleService extends Actor { @Produces(Array("text/html")) def count = (this !! Tick).getOrElse(

Error in counter

) - override def receive: PartialFunction[Any, Unit] = { + def receive = { case Tick => if (hasStartedTicking) { val counter = storage.get(KEY).get.asInstanceOf[Integer].intValue storage.put(KEY, new Integer(counter + 1)) @@ -62,7 +62,7 @@ class PersistentSimpleService extends Actor { @Produces(Array("text/html")) def count = (this !! Tick).getOrElse(

Error in counter

) - override def receive: PartialFunction[Any, Unit] = { + def receive = { case Tick => if (hasStartedTicking) { val counter = storage.get(KEY).get.asInstanceOf[Integer].intValue storage.put(KEY, new Integer(counter + 1)) diff --git a/akka-samples-lift/src/main/scala/bootstrap/liftweb/Boot.scala b/akka-samples-lift/src/main/scala/bootstrap/liftweb/Boot.scala index ae32e277b6..553d90b277 100644 --- a/akka-samples-lift/src/main/scala/bootstrap/liftweb/Boot.scala +++ b/akka-samples-lift/src/main/scala/bootstrap/liftweb/Boot.scala @@ -4,7 +4,6 @@ import _root_.net.liftweb.util._ import _root_.net.liftweb.http._ import _root_.net.liftweb.sitemap._ import _root_.net.liftweb.sitemap.Loc._ -//import _root_.net.liftweb.common._ import _root_.net.liftweb.http.auth._ import Helpers._ @@ -15,9 +14,9 @@ import se.scalablesolutions.akka.util.Logging import sample.lift.{PersistentSimpleService, SimpleService} /** - * A class that's instantiated early and run. It allows the application - * to modify lift's environment - */ + * A class that's instantiated early and run. It allows the application + * to modify lift's environment + */ class Boot { def boot { // where to search snippet @@ -37,21 +36,17 @@ class Boot { LiftRules.passNotFoundToChain = true - object factory extends SupervisorFactory { - override def getSupervisorConfig: SupervisorConfig = { - SupervisorConfig( - RestartStrategy(OneForOne, 3, 100), - Supervise( - new SimpleService, - LifeCycle(Permanent)) :: - Supervise( - new PersistentSimpleService, - LifeCycle(Permanent)) :: - Nil) - } - } - val supervisor = factory.newSupervisor - supervisor.startSupervisor + val factory = SupervisorFactory( + SupervisorConfig( + RestartStrategy(OneForOne, 3, 100), + Supervise( + new SimpleService, + LifeCycle(Permanent)) :: + Supervise( + new PersistentSimpleService, + LifeCycle(Permanent)) :: + Nil)) + factory.newInstance.start // Build SiteMap // val entries = Menu(Loc("Home", List("index"), "Home")) :: Nil diff --git a/akka-samples-scala/src/main/scala/SimpleService.scala b/akka-samples-scala/src/main/scala/SimpleService.scala index 6cb6ed0b8f..e5642171b7 100644 --- a/akka-samples-scala/src/main/scala/SimpleService.scala +++ b/akka-samples-scala/src/main/scala/SimpleService.scala @@ -18,24 +18,20 @@ import org.atmosphere.util.XSSHtmlFilter import org.atmosphere.cpr.BroadcastFilter class Boot { - object factory extends SupervisorFactory { - override def getSupervisorConfig: SupervisorConfig = { - SupervisorConfig( - RestartStrategy(OneForOne, 3, 100), - Supervise( - new SimpleService, - LifeCycle(Permanent)) :: - Supervise( - new Chat, - LifeCycle(Permanent)) :: - Supervise( - new PersistentSimpleService, - LifeCycle(Permanent)) - :: Nil) - } - } - val supervisor = factory.newSupervisor - supervisor.startSupervisor + val factory = SupervisorFactory( + SupervisorConfig( + RestartStrategy(OneForOne, 3, 100), + Supervise( + new SimpleService, + LifeCycle(Permanent)) :: + Supervise( + new Chat, + LifeCycle(Permanent)) :: + Supervise( + new PersistentSimpleService, + LifeCycle(Permanent)) + :: Nil)) + factory.newInstance.start } /** @@ -58,7 +54,7 @@ class SimpleService extends Actor { @Produces(Array("text/html")) def count = (this !! Tick).getOrElse(Error in counter) - override def receive: PartialFunction[Any, Unit] = { + def receive = { case Tick => if (hasStartedTicking) { val counter = storage.get(KEY).get.asInstanceOf[Integer].intValue storage.put(KEY, new Integer(counter + 1)) @@ -91,7 +87,7 @@ class PersistentSimpleService extends Actor { @Produces(Array("text/html")) def count = (this !! Tick).getOrElse(Error in counter) - override def receive: PartialFunction[Any, Unit] = { + def receive = { case Tick => if (hasStartedTicking) { val counter = storage.get(KEY).get.asInstanceOf[Integer].intValue storage.put(KEY, new Integer(counter + 1)) @@ -121,7 +117,7 @@ class Chat extends Actor with Logging { s toString } - override def receive: PartialFunction[Any, Unit] = { + def receive = { case Chat(who, what, msg) => { what match { case "login" => reply("System Message__" + who + " has joined.") diff --git a/akka-samples-security/src/main/scala/SimpleService.scala b/akka-samples-security/src/main/scala/SimpleService.scala index 05bbd75f7b..a0950a2f38 100644 --- a/akka-samples-security/src/main/scala/SimpleService.scala +++ b/akka-samples-security/src/main/scala/SimpleService.scala @@ -11,75 +11,69 @@ import se.scalablesolutions.akka.security.{DigestAuthenticationActor, UserInfo} import se.scalablesolutions.akka.state.TransactionalState class Boot { + val factory = SupervisorFactory( + SupervisorConfig( + RestartStrategy(OneForOne, 3, 100), + // Dummy implementations of all authentication actors + // see akka.conf to enable one of these for the AkkaSecurityFilterFactory + Supervise( + new BasicAuthenticationService, + LifeCycle(Permanent)) :: + /** + Supervise( + new DigestAuthenticationService, + LifeCycle(Permanent)) :: + Supervise( + new SpnegoAuthenticationService, + LifeCycle(Permanent)) :: + **/ + Supervise( + new SecureTickActor, + LifeCycle(Permanent)):: Nil)) - object factory extends SupervisorFactory { - override def getSupervisorConfig: SupervisorConfig = { - SupervisorConfig( - RestartStrategy(OneForOne, 3, 100), - // Dummy implementations of all authentication actors - // see akka.conf to enable one of these for the AkkaSecurityFilterFactory - Supervise( - new BasicAuthenticationService, - LifeCycle(Permanent)) :: - /** - Supervise( - new DigestAuthenticationService, - LifeCycle(Permanent)) :: - Supervise( - new SpnegoAuthenticationService, - LifeCycle(Permanent)) :: - **/ - Supervise( - new SecureTickActor, - LifeCycle(Permanent)):: Nil) - } - - } - - val supervisor = factory.newSupervisor - supervisor.startSupervisor + val supervisor = factory.newInstance + supervisor.start } /* * In akka.conf you can set the FQN of any AuthenticationActor of your wish, under the property name: akka.rest.authenticator */ class DigestAuthenticationService extends DigestAuthenticationActor { - //If you want to have a distributed nonce-map, you can use something like below, - //don't forget to configure your standalone Cassandra instance - // - //makeTransactionRequired - //override def mkNonceMap = PersistentState.newMap(CassandraStorageConfig()).asInstanceOf[scala.collection.mutable.Map[String,Long]] + //If you want to have a distributed nonce-map, you can use something like below, + //don't forget to configure your standalone Cassandra instance + // + //makeTransactionRequired + //override def mkNonceMap = PersistentState.newMap(CassandraStorageConfig()).asInstanceOf[scala.collection.mutable.Map[String,Long]] - //Use an in-memory nonce-map as default - override def mkNonceMap = new scala.collection.mutable.HashMap[String,Long] + //Use an in-memory nonce-map as default + override def mkNonceMap = new scala.collection.mutable.HashMap[String, Long] - //Change this to whatever you want - override def realm = "test" + //Change this to whatever you want + override def realm = "test" - //Dummy method that allows you to log on with whatever username with the password "bar" - override def userInfo(username : String) : Option[UserInfo] = Some(UserInfo(username,"bar","ninja" :: "chef" :: Nil)) + //Dummy method that allows you to log on with whatever username with the password "bar" + override def userInfo(username: String): Option[UserInfo] = Some(UserInfo(username, "bar", "ninja" :: "chef" :: Nil)) } class BasicAuthenticationService extends BasicAuthenticationActor { - //Change this to whatever you want - override def realm = "test" + //Change this to whatever you want + override def realm = "test" - //Dummy method that allows you to log on with whatever username - def verify(odc : Option[BasicCredentials]) : Option[UserInfo] = odc match { - case Some(dc) => userInfo(dc.username) - case _ => None - } + //Dummy method that allows you to log on with whatever username + def verify(odc: Option[BasicCredentials]): Option[UserInfo] = odc match { + case Some(dc) => userInfo(dc.username) + case _ => None + } - //Dummy method that allows you to log on with whatever username with the password "bar" - def userInfo(username : String) : Option[UserInfo] = Some(UserInfo(username,"bar","ninja" :: "chef" :: Nil)) + //Dummy method that allows you to log on with whatever username with the password "bar" + def userInfo(username: String): Option[UserInfo] = Some(UserInfo(username, "bar", "ninja" :: "chef" :: Nil)) } class SpnegoAuthenticationService extends SpnegoAuthenticationActor { - - def rolesFor(user: String) = "ninja" :: "chef" :: Nil + def rolesFor(user: String) = "ninja" :: "chef" :: Nil } @@ -87,16 +81,16 @@ class SpnegoAuthenticationService extends SpnegoAuthenticationActor { * a REST Actor with class level paranoia settings to deny all access * * The interesting part is - * @RolesAllowed - * @PermitAll - * @DenyAll + * @RolesAllowed + * @PermitAll + * @DenyAll */ import java.lang.Integer import javax.annotation.security.{RolesAllowed, DenyAll, PermitAll} import javax.ws.rs.{GET, Path, Produces} + @Path("/secureticker") class SecureTickActor extends Actor with Logging { - makeTransactionRequired case object Tick @@ -131,11 +125,13 @@ class SecureTickActor extends Actor with Logging { def paranoiaTick = tick def tick = (this !! Tick) match { - case(Some(counter)) => (Tick: {counter}) + case (Some(counter)) => (Tick: + {counter} + ) case _ => (Error in counter) } - override def receive: PartialFunction[Any, Unit] = { + def receive = { case Tick => if (hasStartedTicking) { val counter = storage.get(KEY).get.intValue storage.put(KEY, counter + 1) diff --git a/akka-security/src/main/scala/Security.scala b/akka-security/src/main/scala/Security.scala index da02640f36..c8964cb506 100644 --- a/akka-security/src/main/scala/Security.scala +++ b/akka-security/src/main/scala/Security.scala @@ -264,17 +264,18 @@ trait DigestAuthenticationActor extends AuthenticationActor[DigestCredentials] { override def receive = authenticate orElse invalidateNonces override def unauthorized: Response = { - val nonce = randomString(64); + val nonce = randomString(64) nonceMap.put(nonce, System.currentTimeMillis) unauthorized(nonce, "auth", randomString(64)) } def unauthorized(nonce: String, qop: String, opaque: String): Response = { - Response.status(401).header("WWW-Authenticate", + Response.status(401).header( + "WWW-Authenticate", "Digest realm=\"" + realm + "\", " + - "qop=\"" + qop + "\", " + - "nonce=\"" + nonce + "\", " + - "opaque=\"" + opaque + "\"").build + "qop=\"" + qop + "\", " + + "nonce=\"" + nonce + "\", " + + "opaque=\"" + opaque + "\"").build } //Tests wether the specified credentials are valid @@ -284,9 +285,10 @@ trait DigestAuthenticationActor extends AuthenticationActor[DigestCredentials] { val ha1 = h(auth.userName + ":" + auth.realm + ":" + user.password) val ha2 = h(auth.method + ":" + auth.uri) - val response = h(ha1 + ":" + auth.nonce + ":" + - auth.nc + ":" + auth.cnonce + ":" + - auth.qop + ":" + ha2) + val response = h( + ha1 + ":" + auth.nonce + ":" + + auth.nc + ":" + auth.cnonce + ":" + + auth.qop + ":" + ha2) (response == auth.response) && (nonceMap.getOrElse(auth.nonce, -1) != -1) } diff --git a/docs/scaladocs-akka-actors/actor/ActiveObject.scala.html b/docs/scaladocs-akka-actors/actor/ActiveObject.scala.html index 1e86256495..2cc8b693e2 100644 --- a/docs/scaladocs-akka-actors/actor/ActiveObject.scala.html +++ b/docs/scaladocs-akka-actors/actor/ActiveObject.scala.html @@ -135,7 +135,7 @@ object ActiveObject { private[akka] def supervise(restartStrategy: RestartStrategy, components: List[Supervise]): Supervisor = { - object factory extends SupervisorFactory { + val factory = SupervisorFactory { override def getSupervisorConfig = SupervisorConfig(restartStrategy, components) } val supervisor = factory.newSupervisor @@ -333,7 +333,7 @@ private[akka] class Dispatcher(val callbacks: Option[RestartCallbacks]) extends //if (initTxState.isDefined) initTxState.get.setAccessible(true) } - override def receive: PartialFunction[Any, Unit] = { + def receive = { case Invocation(joinPoint, isOneWay, _) => if (Actor.SERIALIZE_MESSAGES) serializeArguments(joinPoint) if (isOneWay) joinPoint.proceed diff --git a/docs/scaladocs-akka-actors/actor/Actor.scala.html b/docs/scaladocs-akka-actors/actor/Actor.scala.html index e6dcc18edb..646df38c48 100644 --- a/docs/scaladocs-akka-actors/actor/Actor.scala.html +++ b/docs/scaladocs-akka-actors/actor/Actor.scala.html @@ -158,7 +158,7 @@ trait Actor extends Logging with TransactionManagement { * <p/> * Example code: * <pre> - * def receive: PartialFunction[Any, Unit] = { + * def receive = { * case Ping => * println("got a ping") * reply("pong") @@ -171,7 +171,7 @@ trait Actor extends Logging with TransactionManagement { * } * </pre> */ - protected def receive: PartialFunction[Any, Unit] + protected def receive /** * User overridable callback/setting. diff --git a/docs/scaladocs-akka-actors/actor/Scheduler.scala.html b/docs/scaladocs-akka-actors/actor/Scheduler.scala.html index 5bca802c80..ff8e609167 100644 --- a/docs/scaladocs-akka-actors/actor/Scheduler.scala.html +++ b/docs/scaladocs-akka-actors/actor/Scheduler.scala.html @@ -38,7 +38,7 @@ case class SchedulerException(msg: String, e: Throwable) extends RuntimeExceptio class ScheduleActor(val receiver: Actor, val future: ScheduledFuture[AnyRef]) extends Actor with Logging { lifeCycleConfig = Some(LifeCycle(Permanent)) - def receive: PartialFunction[Any, Unit] = { + def receive = { case UnSchedule => Scheduler.stopSupervising(this) future.cancel(true) @@ -77,7 +77,7 @@ object Scheduler extends Actor { service.shutdown } - def receive: PartialFunction[Any, Unit] = { + def receive = { case _ => {} // ignore all messages } } diff --git a/docs/scaladocs-akka-actors/actor/Supervisor.scala.html b/docs/scaladocs-akka-actors/actor/Supervisor.scala.html index 18ca63a33c..7a92cdda45 100644 --- a/docs/scaladocs-akka-actors/actor/Supervisor.scala.html +++ b/docs/scaladocs-akka-actors/actor/Supervisor.scala.html @@ -133,7 +133,7 @@ class Supervisor private[akka] (handler: FaultHandlingStrategy) extends Actor wi def stopSupervisor = this ! StopSupervisor - protected def receive: PartialFunction[Any, Unit] = { + protected def receive = { case StartSupervisor => linkedActors.toArray.toList.asInstanceOf[List[Actor]].foreach { actor => actor.start; log.info("Starting actor: %s", actor) } diff --git a/docs/scaladocs-akka-actors/se/scalablesolutions/akka/actor/Actor.html b/docs/scaladocs-akka-actors/se/scalablesolutions/akka/actor/Actor.html index 059539ef3e..972addab96 100644 --- a/docs/scaladocs-akka-actors/se/scalablesolutions/akka/actor/Actor.html +++ b/docs/scaladocs-akka-actors/se/scalablesolutions/akka/actor/Actor.html @@ -278,7 +278,7 @@

Example code:

-     def receive: PartialFunction[Any, Unit] = {
+     def receive = {
        case Ping =>
          println("got a ping")
          reply("pong")
diff --git a/docs/scaladocs-akka-actors/se/scalablesolutions/akka/actor/ScheduleActor.html b/docs/scaladocs-akka-actors/se/scalablesolutions/akka/actor/ScheduleActor.html
index f4bf833de8..81436a04f7 100644
--- a/docs/scaladocs-akka-actors/se/scalablesolutions/akka/actor/ScheduleActor.html
+++ b/docs/scaladocs-akka-actors/se/scalablesolutions/akka/actor/ScheduleActor.html
@@ -287,7 +287,7 @@
    

Example code:

-     def receive: PartialFunction[Any, Unit] = {
+     def receive = {
        case Ping =>
          println("got a ping")
          reply("pong")
diff --git a/docs/scaladocs-akka-actors/se/scalablesolutions/akka/actor/Scheduler$object.html b/docs/scaladocs-akka-actors/se/scalablesolutions/akka/actor/Scheduler$object.html
index 8380573c7a..8d5529b56e 100644
--- a/docs/scaladocs-akka-actors/se/scalablesolutions/akka/actor/Scheduler$object.html
+++ b/docs/scaladocs-akka-actors/se/scalablesolutions/akka/actor/Scheduler$object.html
@@ -282,7 +282,7 @@
    

Example code:

-     def receive: PartialFunction[Any, Unit] = {
+     def receive = {
        case Ping =>
          println("got a ping")
          reply("pong")
diff --git a/docs/scaladocs-akka-actors/se/scalablesolutions/akka/actor/Supervisor.html b/docs/scaladocs-akka-actors/se/scalablesolutions/akka/actor/Supervisor.html
index 7a7d04b067..f19c18da1a 100644
--- a/docs/scaladocs-akka-actors/se/scalablesolutions/akka/actor/Supervisor.html
+++ b/docs/scaladocs-akka-actors/se/scalablesolutions/akka/actor/Supervisor.html
@@ -311,7 +311,7 @@
    

Example code:

-     def receive: PartialFunction[Any, Unit] = {
+     def receive = {
        case Ping =>
          println("got a ping")
          reply("pong")
diff --git a/docs/scaladocs-akka-amqp/AMQP.scala.html b/docs/scaladocs-akka-amqp/AMQP.scala.html
index 4d30a70242..3757fa33b5 100644
--- a/docs/scaladocs-akka-amqp/AMQP.scala.html
+++ b/docs/scaladocs-akka-amqp/AMQP.scala.html
@@ -41,7 +41,7 @@ import java.io.IOException
  *   val consumer = AMQP.newConsumer(params, hostname, port, exchange, ExchangeType.Direct, Serializer.ScalaJSON, None, 100)
  *
  *   consumer ! MessageConsumerListener(queue, routingKey, new Actor() {
- *     def receive: PartialFunction[Any, Unit] = {
+ *     def receive = {
  *       case Message(payload, _, _, _, _) => log.debug("Received message: %s", payload)
  *     }
  *   })
@@ -209,7 +209,7 @@ object AMQP extends Actor {
 
     log.info("AMQP.Producer [%s] is started", toString)
 
-    def receive: PartialFunction[Any, Unit] = {
+    def receive = {
       case message @ Message(payload, routingKey, mandatory, immediate, properties) =>
         log.debug("Sending message [%s]", message)
         channel.basicPublish(exchangeName, routingKey, mandatory, immediate, properties, serializer.out(payload))
@@ -312,7 +312,7 @@ object AMQP extends Actor {
       listener.tag = Some(listenerTag)
     }
 
-    def receive: PartialFunction[Any, Unit] = {
+    def receive = {
       case listener: MessageConsumerListener =>
         startLink(listener.actor)
         listeners.put(listener, listener)
@@ -425,7 +425,7 @@ object AMQP extends Actor {
     override def postRestart(reason: AnyRef, config: Option[AnyRef]) = reconnect(initReconnectDelay)
   }
 
-  def receive: PartialFunction[Any, Unit] = {
+  def receive = {
     case _ => {} // ignore all messages
   }
 }
diff --git a/docs/scaladocs-akka-amqp/ExampleSession.scala.html b/docs/scaladocs-akka-amqp/ExampleSession.scala.html
index a937fbf14f..6495493289 100644
--- a/docs/scaladocs-akka-amqp/ExampleSession.scala.html
+++ b/docs/scaladocs-akka-amqp/ExampleSession.scala.html
@@ -40,7 +40,7 @@ object ExampleSession {
   def direct = {
     val consumer = AMQP.newConsumer(CONFIG, HOSTNAME, PORT, IM, ExchangeType.Direct, SERIALIZER, None, 100, false, false, Map[String, AnyRef]())
     consumer ! MessageConsumerListener("@george_bush", "direct", new Actor() {
-      def receive: PartialFunction[Any, Unit] = {
+      def receive = {
         case Message(payload, _, _, _, _) => log.info("@george_bush received message from: %s", payload)
       }
     })
@@ -51,12 +51,12 @@ object ExampleSession {
   def fanout = {
     val consumer = AMQP.newConsumer(CONFIG, HOSTNAME, PORT, CHAT, ExchangeType.Fanout, SERIALIZER, None, 100, false, false, Map[String, AnyRef]())
     consumer ! MessageConsumerListener("@george_bush", "", new Actor() {
-      def receive: PartialFunction[Any, Unit] = {
+      def receive = {
         case Message(payload, _, _, _, _) => log.info("@george_bush received message from: %s", payload)
       }
     })
     consumer ! MessageConsumerListener("@barack_obama", "", new Actor() {
-      def receive: PartialFunction[Any, Unit] = {
+      def receive = {
         case Message(payload, _, _, _, _) => log.info("@barack_obama received message from: %s", payload)
       }
     })
diff --git a/docs/scaladocs-akka-amqp/se/scalablesolutions/akka/amqp/AMQP$object.html b/docs/scaladocs-akka-amqp/se/scalablesolutions/akka/amqp/AMQP$object.html
index 827f8ffac8..ed8087c7c1 100644
--- a/docs/scaladocs-akka-amqp/se/scalablesolutions/akka/amqp/AMQP$object.html
+++ b/docs/scaladocs-akka-amqp/se/scalablesolutions/akka/amqp/AMQP$object.html
@@ -63,7 +63,7 @@
    val consumer = AMQP.newConsumer(params, hostname, port, exchange, ExchangeType.Direct, Serializer.ScalaJSON, None, 100)
 
    consumer ! MessageConsumerListener(queue, routingKey, new Actor() {
-     def receive: PartialFunction[Any, Unit] = {
+     def receive = {
        case Message(payload, _, _, _, _) => log.debug("Received message: %s", payload)
      }
    })
diff --git a/docs/scaladocs-akka-security/Security.scala.html b/docs/scaladocs-akka-security/Security.scala.html
index ce150f8bfc..8620ec9d74 100644
--- a/docs/scaladocs-akka-security/Security.scala.html
+++ b/docs/scaladocs-akka-security/Security.scala.html
@@ -211,7 +211,7 @@ trait AuthenticationActor[C <: Credentials] extends Actor with Logging
         }
     }
 
-    override def receive: PartialFunction[Any, Unit] = authenticate
+    def receive = authenticate
 
     //returns the string value of the "Authorization"-header of the request
     def auth(r : Req) = r.getHeaderValue("Authorization")
@@ -284,7 +284,7 @@ trait DigestAuthenticationActor extends AuthenticationActor[DigestCredentials]
     Scheduler.schedule(this, InvalidateNonces, noncePurgeInterval, noncePurgeInterval, TimeUnit.MILLISECONDS )
 
     //authenticate or invalidate nonces
-    override def receive: PartialFunction[Any, Unit] = authenticate orElse invalidateNonces
+    def receive = authenticate orElse invalidateNonces
 
     override def unauthorized : Response =
     {
diff --git a/docs/scaladocs-akka-security/se/scalablesolutions/akka/security/AuthenticationActor.html b/docs/scaladocs-akka-security/se/scalablesolutions/akka/security/AuthenticationActor.html
index 9d9812df82..460dd68825 100644
--- a/docs/scaladocs-akka-security/se/scalablesolutions/akka/security/AuthenticationActor.html
+++ b/docs/scaladocs-akka-security/se/scalablesolutions/akka/security/AuthenticationActor.html
@@ -253,7 +253,7 @@
         receive..
       
       
-        override def receive
+        def receive
         
         
       
diff --git a/docs/scaladocs-akka-security/se/scalablesolutions/akka/security/BasicAuthenticationActor.html b/docs/scaladocs-akka-security/se/scalablesolutions/akka/security/BasicAuthenticationActor.html
index 3afa719cdb..2e4f01c012 100644
--- a/docs/scaladocs-akka-security/se/scalablesolutions/akka/security/BasicAuthenticationActor.html
+++ b/docs/scaladocs-akka-security/se/scalablesolutions/akka/security/BasicAuthenticationActor.html
@@ -251,7 +251,7 @@
         receive..
       
       
-        override def receive
+        def receive
         
         
       
diff --git a/docs/scaladocs-akka-security/se/scalablesolutions/akka/security/DigestAuthenticationActor.html b/docs/scaladocs-akka-security/se/scalablesolutions/akka/security/DigestAuthenticationActor.html
index 97195537fa..e33418278a 100644
--- a/docs/scaladocs-akka-security/se/scalablesolutions/akka/security/DigestAuthenticationActor.html
+++ b/docs/scaladocs-akka-security/se/scalablesolutions/akka/security/DigestAuthenticationActor.html
@@ -321,7 +321,7 @@
         receive..
       
       
-        override def receive
+        def receive
         
         
       
diff --git a/docs/scaladocs-akka-security/se/scalablesolutions/akka/security/SpnegoAuthenticationActor.html b/docs/scaladocs-akka-security/se/scalablesolutions/akka/security/SpnegoAuthenticationActor.html
index 8cf953060b..ab70c641ee 100644
--- a/docs/scaladocs-akka-security/se/scalablesolutions/akka/security/SpnegoAuthenticationActor.html
+++ b/docs/scaladocs-akka-security/se/scalablesolutions/akka/security/SpnegoAuthenticationActor.html
@@ -276,7 +276,7 @@
         receive..
       
       
-        override def receive
+        def receive
         
         
       

From e9f4f9a88676794a288fb445988693929287b13e Mon Sep 17 00:00:00 2001
From: jboner 
Date: Fri, 20 Nov 2009 08:30:06 +0100
Subject: [PATCH 02/20] removed the .idea dirr

---
 .idea/artifacts/akka_samples_lift_war.xml     |   8 -
 .../akka_samples_lift_war_exploded.xml        |  13 -
 .idea/compiler.xml                            |  31 -
 .idea/copyright/profiles_settings.xml         |   5 -
 .idea/encodings.xml                           |   5 -
 .../Maven__aopalliance_aopalliance_1_0.xml    |  13 -
 .idea/libraries/Maven__asm_asm_3_1.xml        |  13 -
 .../libraries/Maven__asm_asm_commons_3_1.xml  |  13 -
 .idea/libraries/Maven__asm_asm_tree_3_1.xml   |  13 -
 .idea/libraries/Maven__asm_asm_util_3_1.xml   |  13 -
 .idea/libraries/Maven__cglib_cglib_2_2.xml    |  13 -
 .../Maven__com_facebook_thrift_1_0.xml        |  13 -
 ...tions_google_collect_snapshot_20080530.xml |  13 -
 .../Maven__com_mongodb_mongo_0_6.xml          |  13 -
 ...en__com_rabbitmq_rabbitmq_client_0_9_1.xml |  13 -
 ..._com_sun_grizzly_grizzly_comet_1_8_6_3.xml |  13 -
 ...rizzly_grizzly_comet_webserver_1_8_6_3.xml |  13 -
 ..._sun_grizzly_grizzly_framework_1_8_6_3.xml |  13 -
 ...__com_sun_grizzly_grizzly_http_1_8_6_3.xml |  13 -
 ...n_grizzly_grizzly_http_servlet_1_8_6_3.xml |  13 -
 ...sun_grizzly_grizzly_http_utils_1_8_6_3.xml |  13 -
 ...m_sun_grizzly_grizzly_portunif_1_8_6_3.xml |  13 -
 ...n__com_sun_grizzly_grizzly_rcm_1_8_6_3.xml |  13 -
 ...zzly_grizzly_servlet_webserver_1_8_6_3.xml |  13 -
 ..._jersey_contribs_jersey_scala_1_1_3_ea.xml |  13 -
 ...n__com_sun_jersey_jersey_atom_1_1_3_ea.xml |  13 -
 ..._com_sun_jersey_jersey_client_1_1_3_ea.xml |  13 -
 ...n__com_sun_jersey_jersey_core_1_1_3_ea.xml |  13 -
 ...n__com_sun_jersey_jersey_json_1_1_3_ea.xml |  13 -
 ..._com_sun_jersey_jersey_server_1_1_3_ea.xml |  13 -
 ...ven__com_sun_xml_bind_jaxb_impl_2_1_12.xml |  13 -
 ...aven__com_sun_xml_bind_jaxb_impl_2_1_6.xml |  13 -
 ...Maven__commons_codec_commons_codec_1_3.xml |  13 -
 ..._collections_commons_collections_3_2_1.xml |  13 -
 ...ns_fileupload_commons_fileupload_1_2_1.xml |  13 -
 ...mons_httpclient_commons_httpclient_3_1.xml |  13 -
 .../Maven__commons_io_commons_io_1_4.xml      |  13 -
 ..._commons_logging_commons_logging_1_0_4.xml |  13 -
 ...ommons_logging_commons_logging_api_1_1.xml |  13 -
 ...Maven__commons_pool_commons_pool_1_5_1.xml |  13 -
 ...ven__dispatch_http_dispatch_http_0_5_2.xml |  13 -
 ...ven__dispatch_json_dispatch_json_0_5_2.xml |  13 -
 ...Maven__javax_activation_activation_1_1.xml |  13 -
 ...om_springsource_javax_annotation_1_0_0.xml |  13 -
 ...Maven__javax_annotation_jsr250_api_1_0.xml |  13 -
 .../libraries/Maven__javax_mail_mail_1_4.xml  |  13 -
 .../Maven__javax_servlet_servlet_api_2_5.xml  |  13 -
 .../Maven__javax_ws_rs_jsr311_api_1_0.xml     |  13 -
 .../Maven__javax_ws_rs_jsr311_api_1_1.xml     |  13 -
 .../Maven__javax_xml_bind_jaxb_api_2_1.xml    |  13 -
 ...Maven__javax_xml_stream_stax_api_1_0_2.xml |  13 -
 .idea/libraries/Maven__jdom_jdom_1_0.xml      |  13 -
 .idea/libraries/Maven__junit_junit_4_4.xml    |  13 -
 .idea/libraries/Maven__junit_junit_4_5.xml    |  13 -
 .idea/libraries/Maven__log4j_log4j_1_2_13.xml |  13 -
 ...ven__markdownj_markdownj_1_0_2b4_0_3_0.xml |  13 -
 .../libraries/Maven__net_lag_configgy_1_3.xml |  13 -
 .../libraries/Maven__net_lag_configgy_1_4.xml |  13 -
 .../Maven__net_liftweb_lift_util_1_1_M6.xml   |  13 -
 ...com_springsource_org_aopalliance_1_0_0.xml |  13 -
 ...g_apache_camel_camel_core_2_0_SNAPSHOT.xml |  13 -
 ...__org_apache_cassandra_cassandra_0_4_1.xml |  13 -
 .../Maven__org_apache_zookeeper_3_1_0.xml     |  13 -
 ...org_atmosphere_atmosphere_compat_0_4_1.xml |  13 -
 ...tmosphere_atmosphere_core_0_4_SNAPSHOT.xml |  13 -
 ...mosphere_portable_runtime_0_4_SNAPSHOT.xml |  13 -
 ...rg_atmosphere_atmosphere_runtime_0_4_1.xml |  13 -
 ...ehaus_aspectwerkz_aspectwerkz_jdk5_2_1.xml |  13 -
 ...spectwerkz_aspectwerkz_nodeps_jdk5_2_1.xml |  13 -
 ...odehaus_jackson_jackson_core_asl_1_1_0.xml |  13 -
 ...ehaus_jackson_jackson_mapper_asl_1_1_0.xml |  13 -
 ...en__org_codehaus_jettison_jettison_1_1.xml |  13 -
 .../Maven__org_guiceyfruit_guice_all_2_0.xml  |  13 -
 ..._org_guiceyfruit_guice_core_2_0_beta_4.xml |  13 -
 ...__org_guiceyfruit_guiceyfruit_core_2_0.xml |  13 -
 .../Maven__org_hamcrest_hamcrest_core_1_1.xml |  13 -
 ...ven__org_hamcrest_hamcrest_library_1_1.xml |  13 -
 .../Maven__org_jboss_netty_netty_3_1_0_GA.xml |  13 -
 .../Maven__org_jmock_jmock_2_4_0.xml          |  13 -
 .../Maven__org_mockito_mockito_all_1_8_0.xml  |  13 -
 ...ltiverse_multiverse_alpha_0_3_SNAPSHOT.xml |  13 -
 ...ultiverse_multiverse_core_0_3_SNAPSHOT.xml |  13 -
 ...n__org_scala_lang_scala_compiler_2_7_4.xml |  13 -
 ...n__org_scala_lang_scala_compiler_2_7_5.xml |  13 -
 ...en__org_scala_lang_scala_library_2_7_5.xml |  13 -
 ...n__org_scala_tools_javautils_2_7_4_0_1.xml |  13 -
 ...n__org_scala_tools_testing_specs_1_4_4.xml |  13 -
 ...en__org_scala_tools_vscaladoc_1_1_md_3.xml |  13 -
 .../Maven__org_scalatest_scalatest_1_0.xml    |  13 -
 .../Maven__org_slf4j_slf4j_api_1_4_3.xml      |  13 -
 .../Maven__org_slf4j_slf4j_log4j12_1_4_3.xml  |  13 -
 .idea/libraries/Maven__rome_rome_0_9.xml      |  13 -
 .../libraries/Maven__sbinary_sbinary_0_3.xml  |  13 -
 .../libraries/Maven__sjson_json_sjson_0_2.xml |  13 -
 .../libraries/Maven__stax_stax_api_1_0_1.xml  |  13 -
 .idea/misc.xml                                |  73 --
 .idea/modules.xml                             |  23 -
 .idea/uiDesigner.xml                          | 125 ----
 .idea/vcs.xml                                 |   8 -
 .idea/workspace.xml                           | 638 ------------------
 100 files changed, 2099 deletions(-)
 delete mode 100644 .idea/artifacts/akka_samples_lift_war.xml
 delete mode 100644 .idea/artifacts/akka_samples_lift_war_exploded.xml
 delete mode 100644 .idea/compiler.xml
 delete mode 100644 .idea/copyright/profiles_settings.xml
 delete mode 100644 .idea/encodings.xml
 delete mode 100644 .idea/libraries/Maven__aopalliance_aopalliance_1_0.xml
 delete mode 100644 .idea/libraries/Maven__asm_asm_3_1.xml
 delete mode 100644 .idea/libraries/Maven__asm_asm_commons_3_1.xml
 delete mode 100644 .idea/libraries/Maven__asm_asm_tree_3_1.xml
 delete mode 100644 .idea/libraries/Maven__asm_asm_util_3_1.xml
 delete mode 100644 .idea/libraries/Maven__cglib_cglib_2_2.xml
 delete mode 100644 .idea/libraries/Maven__com_facebook_thrift_1_0.xml
 delete mode 100644 .idea/libraries/Maven__com_google_code_google_collections_google_collect_snapshot_20080530.xml
 delete mode 100644 .idea/libraries/Maven__com_mongodb_mongo_0_6.xml
 delete mode 100644 .idea/libraries/Maven__com_rabbitmq_rabbitmq_client_0_9_1.xml
 delete mode 100644 .idea/libraries/Maven__com_sun_grizzly_grizzly_comet_1_8_6_3.xml
 delete mode 100644 .idea/libraries/Maven__com_sun_grizzly_grizzly_comet_webserver_1_8_6_3.xml
 delete mode 100644 .idea/libraries/Maven__com_sun_grizzly_grizzly_framework_1_8_6_3.xml
 delete mode 100644 .idea/libraries/Maven__com_sun_grizzly_grizzly_http_1_8_6_3.xml
 delete mode 100644 .idea/libraries/Maven__com_sun_grizzly_grizzly_http_servlet_1_8_6_3.xml
 delete mode 100644 .idea/libraries/Maven__com_sun_grizzly_grizzly_http_utils_1_8_6_3.xml
 delete mode 100644 .idea/libraries/Maven__com_sun_grizzly_grizzly_portunif_1_8_6_3.xml
 delete mode 100644 .idea/libraries/Maven__com_sun_grizzly_grizzly_rcm_1_8_6_3.xml
 delete mode 100644 .idea/libraries/Maven__com_sun_grizzly_grizzly_servlet_webserver_1_8_6_3.xml
 delete mode 100644 .idea/libraries/Maven__com_sun_jersey_contribs_jersey_scala_1_1_3_ea.xml
 delete mode 100644 .idea/libraries/Maven__com_sun_jersey_jersey_atom_1_1_3_ea.xml
 delete mode 100644 .idea/libraries/Maven__com_sun_jersey_jersey_client_1_1_3_ea.xml
 delete mode 100644 .idea/libraries/Maven__com_sun_jersey_jersey_core_1_1_3_ea.xml
 delete mode 100644 .idea/libraries/Maven__com_sun_jersey_jersey_json_1_1_3_ea.xml
 delete mode 100644 .idea/libraries/Maven__com_sun_jersey_jersey_server_1_1_3_ea.xml
 delete mode 100644 .idea/libraries/Maven__com_sun_xml_bind_jaxb_impl_2_1_12.xml
 delete mode 100644 .idea/libraries/Maven__com_sun_xml_bind_jaxb_impl_2_1_6.xml
 delete mode 100644 .idea/libraries/Maven__commons_codec_commons_codec_1_3.xml
 delete mode 100644 .idea/libraries/Maven__commons_collections_commons_collections_3_2_1.xml
 delete mode 100644 .idea/libraries/Maven__commons_fileupload_commons_fileupload_1_2_1.xml
 delete mode 100644 .idea/libraries/Maven__commons_httpclient_commons_httpclient_3_1.xml
 delete mode 100644 .idea/libraries/Maven__commons_io_commons_io_1_4.xml
 delete mode 100644 .idea/libraries/Maven__commons_logging_commons_logging_1_0_4.xml
 delete mode 100644 .idea/libraries/Maven__commons_logging_commons_logging_api_1_1.xml
 delete mode 100644 .idea/libraries/Maven__commons_pool_commons_pool_1_5_1.xml
 delete mode 100644 .idea/libraries/Maven__dispatch_http_dispatch_http_0_5_2.xml
 delete mode 100644 .idea/libraries/Maven__dispatch_json_dispatch_json_0_5_2.xml
 delete mode 100644 .idea/libraries/Maven__javax_activation_activation_1_1.xml
 delete mode 100644 .idea/libraries/Maven__javax_annotation_com_springsource_javax_annotation_1_0_0.xml
 delete mode 100644 .idea/libraries/Maven__javax_annotation_jsr250_api_1_0.xml
 delete mode 100644 .idea/libraries/Maven__javax_mail_mail_1_4.xml
 delete mode 100644 .idea/libraries/Maven__javax_servlet_servlet_api_2_5.xml
 delete mode 100644 .idea/libraries/Maven__javax_ws_rs_jsr311_api_1_0.xml
 delete mode 100644 .idea/libraries/Maven__javax_ws_rs_jsr311_api_1_1.xml
 delete mode 100644 .idea/libraries/Maven__javax_xml_bind_jaxb_api_2_1.xml
 delete mode 100644 .idea/libraries/Maven__javax_xml_stream_stax_api_1_0_2.xml
 delete mode 100644 .idea/libraries/Maven__jdom_jdom_1_0.xml
 delete mode 100644 .idea/libraries/Maven__junit_junit_4_4.xml
 delete mode 100644 .idea/libraries/Maven__junit_junit_4_5.xml
 delete mode 100644 .idea/libraries/Maven__log4j_log4j_1_2_13.xml
 delete mode 100644 .idea/libraries/Maven__markdownj_markdownj_1_0_2b4_0_3_0.xml
 delete mode 100644 .idea/libraries/Maven__net_lag_configgy_1_3.xml
 delete mode 100644 .idea/libraries/Maven__net_lag_configgy_1_4.xml
 delete mode 100644 .idea/libraries/Maven__net_liftweb_lift_util_1_1_M6.xml
 delete mode 100644 .idea/libraries/Maven__org_aopalliance_com_springsource_org_aopalliance_1_0_0.xml
 delete mode 100644 .idea/libraries/Maven__org_apache_camel_camel_core_2_0_SNAPSHOT.xml
 delete mode 100644 .idea/libraries/Maven__org_apache_cassandra_cassandra_0_4_1.xml
 delete mode 100644 .idea/libraries/Maven__org_apache_zookeeper_3_1_0.xml
 delete mode 100644 .idea/libraries/Maven__org_atmosphere_atmosphere_compat_0_4_1.xml
 delete mode 100644 .idea/libraries/Maven__org_atmosphere_atmosphere_core_0_4_SNAPSHOT.xml
 delete mode 100644 .idea/libraries/Maven__org_atmosphere_atmosphere_portable_runtime_0_4_SNAPSHOT.xml
 delete mode 100644 .idea/libraries/Maven__org_atmosphere_atmosphere_runtime_0_4_1.xml
 delete mode 100644 .idea/libraries/Maven__org_codehaus_aspectwerkz_aspectwerkz_jdk5_2_1.xml
 delete mode 100644 .idea/libraries/Maven__org_codehaus_aspectwerkz_aspectwerkz_nodeps_jdk5_2_1.xml
 delete mode 100644 .idea/libraries/Maven__org_codehaus_jackson_jackson_core_asl_1_1_0.xml
 delete mode 100644 .idea/libraries/Maven__org_codehaus_jackson_jackson_mapper_asl_1_1_0.xml
 delete mode 100644 .idea/libraries/Maven__org_codehaus_jettison_jettison_1_1.xml
 delete mode 100644 .idea/libraries/Maven__org_guiceyfruit_guice_all_2_0.xml
 delete mode 100644 .idea/libraries/Maven__org_guiceyfruit_guice_core_2_0_beta_4.xml
 delete mode 100644 .idea/libraries/Maven__org_guiceyfruit_guiceyfruit_core_2_0.xml
 delete mode 100644 .idea/libraries/Maven__org_hamcrest_hamcrest_core_1_1.xml
 delete mode 100644 .idea/libraries/Maven__org_hamcrest_hamcrest_library_1_1.xml
 delete mode 100644 .idea/libraries/Maven__org_jboss_netty_netty_3_1_0_GA.xml
 delete mode 100644 .idea/libraries/Maven__org_jmock_jmock_2_4_0.xml
 delete mode 100644 .idea/libraries/Maven__org_mockito_mockito_all_1_8_0.xml
 delete mode 100644 .idea/libraries/Maven__org_multiverse_multiverse_alpha_0_3_SNAPSHOT.xml
 delete mode 100644 .idea/libraries/Maven__org_multiverse_multiverse_core_0_3_SNAPSHOT.xml
 delete mode 100644 .idea/libraries/Maven__org_scala_lang_scala_compiler_2_7_4.xml
 delete mode 100644 .idea/libraries/Maven__org_scala_lang_scala_compiler_2_7_5.xml
 delete mode 100644 .idea/libraries/Maven__org_scala_lang_scala_library_2_7_5.xml
 delete mode 100644 .idea/libraries/Maven__org_scala_tools_javautils_2_7_4_0_1.xml
 delete mode 100644 .idea/libraries/Maven__org_scala_tools_testing_specs_1_4_4.xml
 delete mode 100644 .idea/libraries/Maven__org_scala_tools_vscaladoc_1_1_md_3.xml
 delete mode 100644 .idea/libraries/Maven__org_scalatest_scalatest_1_0.xml
 delete mode 100644 .idea/libraries/Maven__org_slf4j_slf4j_api_1_4_3.xml
 delete mode 100644 .idea/libraries/Maven__org_slf4j_slf4j_log4j12_1_4_3.xml
 delete mode 100644 .idea/libraries/Maven__rome_rome_0_9.xml
 delete mode 100644 .idea/libraries/Maven__sbinary_sbinary_0_3.xml
 delete mode 100644 .idea/libraries/Maven__sjson_json_sjson_0_2.xml
 delete mode 100644 .idea/libraries/Maven__stax_stax_api_1_0_1.xml
 delete mode 100644 .idea/misc.xml
 delete mode 100644 .idea/modules.xml
 delete mode 100644 .idea/uiDesigner.xml
 delete mode 100644 .idea/vcs.xml
 delete mode 100644 .idea/workspace.xml

diff --git a/.idea/artifacts/akka_samples_lift_war.xml b/.idea/artifacts/akka_samples_lift_war.xml
deleted file mode 100644
index 2131d479ef..0000000000
--- a/.idea/artifacts/akka_samples_lift_war.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-
-  
-    $PROJECT_DIR$/akka-samples-lift/target
-    
-      
-    
-  
-
\ No newline at end of file
diff --git a/.idea/artifacts/akka_samples_lift_war_exploded.xml b/.idea/artifacts/akka_samples_lift_war_exploded.xml
deleted file mode 100644
index 9f98b24e5b..0000000000
--- a/.idea/artifacts/akka_samples_lift_war_exploded.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-  
-    $PROJECT_DIR$/akka-samples-lift/target/akka-samples-lift-0.6
-    
-      
-      
-        
-          
-        
-      
-    
-  
-
\ No newline at end of file
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
deleted file mode 100644
index 4352577bf3..0000000000
--- a/.idea/compiler.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-
-
-  
-    
-  
-    
-
-
diff --git a/.idea/copyright/profiles_settings.xml b/.idea/copyright/profiles_settings.xml
deleted file mode 100644
index 3572571ad8..0000000000
--- a/.idea/copyright/profiles_settings.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-
-  
-    
-  
-
\ No newline at end of file
diff --git a/.idea/encodings.xml b/.idea/encodings.xml
deleted file mode 100644
index e206d70d85..0000000000
--- a/.idea/encodings.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-  
-
-
diff --git a/.idea/libraries/Maven__aopalliance_aopalliance_1_0.xml b/.idea/libraries/Maven__aopalliance_aopalliance_1_0.xml
deleted file mode 100644
index 30ff5cb791..0000000000
--- a/.idea/libraries/Maven__aopalliance_aopalliance_1_0.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-  
-    
-      
-    
-    
-      
-    
-    
-      
-    
-  
-
\ No newline at end of file
diff --git a/.idea/libraries/Maven__asm_asm_3_1.xml b/.idea/libraries/Maven__asm_asm_3_1.xml
deleted file mode 100644
index 3386f109a9..0000000000
--- a/.idea/libraries/Maven__asm_asm_3_1.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-  
-    
-      
-    
-    
-      
-    
-    
-      
-    
-  
-
\ No newline at end of file
diff --git a/.idea/libraries/Maven__asm_asm_commons_3_1.xml b/.idea/libraries/Maven__asm_asm_commons_3_1.xml
deleted file mode 100644
index 453a1d7626..0000000000
--- a/.idea/libraries/Maven__asm_asm_commons_3_1.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-  
-    
-      
-    
-    
-      
-    
-    
-      
-    
-  
-
\ No newline at end of file
diff --git a/.idea/libraries/Maven__asm_asm_tree_3_1.xml b/.idea/libraries/Maven__asm_asm_tree_3_1.xml
deleted file mode 100644
index 05bc5d5e48..0000000000
--- a/.idea/libraries/Maven__asm_asm_tree_3_1.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-  
-    
-      
-    
-    
-      
-    
-    
-      
-    
-  
-
\ No newline at end of file
diff --git a/.idea/libraries/Maven__asm_asm_util_3_1.xml b/.idea/libraries/Maven__asm_asm_util_3_1.xml
deleted file mode 100644
index 158686fbf5..0000000000
--- a/.idea/libraries/Maven__asm_asm_util_3_1.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-  
-    
-      
-    
-    
-      
-    
-    
-      
-    
-  
-
\ No newline at end of file
diff --git a/.idea/libraries/Maven__cglib_cglib_2_2.xml b/.idea/libraries/Maven__cglib_cglib_2_2.xml
deleted file mode 100644
index 01d9b10a4f..0000000000
--- a/.idea/libraries/Maven__cglib_cglib_2_2.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-  
-    
-      
-    
-    
-      
-    
-    
-      
-    
-  
-
\ No newline at end of file
diff --git a/.idea/libraries/Maven__com_facebook_thrift_1_0.xml b/.idea/libraries/Maven__com_facebook_thrift_1_0.xml
deleted file mode 100644
index 8dcb4b463b..0000000000
--- a/.idea/libraries/Maven__com_facebook_thrift_1_0.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-  
-    
-      
-    
-    
-      
-    
-    
-      
-    
-  
-
\ No newline at end of file
diff --git a/.idea/libraries/Maven__com_google_code_google_collections_google_collect_snapshot_20080530.xml b/.idea/libraries/Maven__com_google_code_google_collections_google_collect_snapshot_20080530.xml
deleted file mode 100644
index dbb527976c..0000000000
--- a/.idea/libraries/Maven__com_google_code_google_collections_google_collect_snapshot_20080530.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-  
-    
-      
-    
-    
-      
-    
-    
-      
-    
-  
-
\ No newline at end of file
diff --git a/.idea/libraries/Maven__com_mongodb_mongo_0_6.xml b/.idea/libraries/Maven__com_mongodb_mongo_0_6.xml
deleted file mode 100644
index 1111a5e3bb..0000000000
--- a/.idea/libraries/Maven__com_mongodb_mongo_0_6.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-  
-    
-      
-    
-    
-      
-    
-    
-      
-    
-  
-
\ No newline at end of file
diff --git a/.idea/libraries/Maven__com_rabbitmq_rabbitmq_client_0_9_1.xml b/.idea/libraries/Maven__com_rabbitmq_rabbitmq_client_0_9_1.xml
deleted file mode 100644
index b88e7116c2..0000000000
--- a/.idea/libraries/Maven__com_rabbitmq_rabbitmq_client_0_9_1.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-  
-    
-      
-    
-    
-      
-    
-    
-      
-    
-  
-
\ No newline at end of file
diff --git a/.idea/libraries/Maven__com_sun_grizzly_grizzly_comet_1_8_6_3.xml b/.idea/libraries/Maven__com_sun_grizzly_grizzly_comet_1_8_6_3.xml
deleted file mode 100644
index 9217c09460..0000000000
--- a/.idea/libraries/Maven__com_sun_grizzly_grizzly_comet_1_8_6_3.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-  
-    
-      
-    
-    
-      
-    
-    
-      
-    
-  
-
\ No newline at end of file
diff --git a/.idea/libraries/Maven__com_sun_grizzly_grizzly_comet_webserver_1_8_6_3.xml b/.idea/libraries/Maven__com_sun_grizzly_grizzly_comet_webserver_1_8_6_3.xml
deleted file mode 100644
index 42e7c4dd91..0000000000
--- a/.idea/libraries/Maven__com_sun_grizzly_grizzly_comet_webserver_1_8_6_3.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-  
-    
-      
-    
-    
-      
-    
-    
-      
-    
-  
-
\ No newline at end of file
diff --git a/.idea/libraries/Maven__com_sun_grizzly_grizzly_framework_1_8_6_3.xml b/.idea/libraries/Maven__com_sun_grizzly_grizzly_framework_1_8_6_3.xml
deleted file mode 100644
index 8efce0135c..0000000000
--- a/.idea/libraries/Maven__com_sun_grizzly_grizzly_framework_1_8_6_3.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-  
-    
-      
-    
-    
-      
-    
-    
-      
-    
-  
-
\ No newline at end of file
diff --git a/.idea/libraries/Maven__com_sun_grizzly_grizzly_http_1_8_6_3.xml b/.idea/libraries/Maven__com_sun_grizzly_grizzly_http_1_8_6_3.xml
deleted file mode 100644
index 3f949d7a05..0000000000
--- a/.idea/libraries/Maven__com_sun_grizzly_grizzly_http_1_8_6_3.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-  
-    
-      
-    
-    
-      
-    
-    
-      
-    
-  
-
\ No newline at end of file
diff --git a/.idea/libraries/Maven__com_sun_grizzly_grizzly_http_servlet_1_8_6_3.xml b/.idea/libraries/Maven__com_sun_grizzly_grizzly_http_servlet_1_8_6_3.xml
deleted file mode 100644
index 3ca706b8aa..0000000000
--- a/.idea/libraries/Maven__com_sun_grizzly_grizzly_http_servlet_1_8_6_3.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-  
-    
-      
-    
-    
-      
-    
-    
-      
-    
-  
-
\ No newline at end of file
diff --git a/.idea/libraries/Maven__com_sun_grizzly_grizzly_http_utils_1_8_6_3.xml b/.idea/libraries/Maven__com_sun_grizzly_grizzly_http_utils_1_8_6_3.xml
deleted file mode 100644
index 8d74adca82..0000000000
--- a/.idea/libraries/Maven__com_sun_grizzly_grizzly_http_utils_1_8_6_3.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-  
-    
-      
-    
-    
-      
-    
-    
-      
-    
-  
-
\ No newline at end of file
diff --git a/.idea/libraries/Maven__com_sun_grizzly_grizzly_portunif_1_8_6_3.xml b/.idea/libraries/Maven__com_sun_grizzly_grizzly_portunif_1_8_6_3.xml
deleted file mode 100644
index cb1f76d311..0000000000
--- a/.idea/libraries/Maven__com_sun_grizzly_grizzly_portunif_1_8_6_3.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-  
-    
-      
-    
-    
-      
-    
-    
-      
-    
-  
-
\ No newline at end of file
diff --git a/.idea/libraries/Maven__com_sun_grizzly_grizzly_rcm_1_8_6_3.xml b/.idea/libraries/Maven__com_sun_grizzly_grizzly_rcm_1_8_6_3.xml
deleted file mode 100644
index 4705ee66ce..0000000000
--- a/.idea/libraries/Maven__com_sun_grizzly_grizzly_rcm_1_8_6_3.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-  
-    
-      
-    
-    
-      
-    
-    
-      
-    
-  
-
\ No newline at end of file
diff --git a/.idea/libraries/Maven__com_sun_grizzly_grizzly_servlet_webserver_1_8_6_3.xml b/.idea/libraries/Maven__com_sun_grizzly_grizzly_servlet_webserver_1_8_6_3.xml
deleted file mode 100644
index 54ed7d4f5f..0000000000
--- a/.idea/libraries/Maven__com_sun_grizzly_grizzly_servlet_webserver_1_8_6_3.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-  
-    
-      
-    
-    
-      
-    
-    
-      
-    
-  
-
\ No newline at end of file
diff --git a/.idea/libraries/Maven__com_sun_jersey_contribs_jersey_scala_1_1_3_ea.xml b/.idea/libraries/Maven__com_sun_jersey_contribs_jersey_scala_1_1_3_ea.xml
deleted file mode 100644
index 8781880910..0000000000
--- a/.idea/libraries/Maven__com_sun_jersey_contribs_jersey_scala_1_1_3_ea.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-  
-    
-      
-    
-    
-      
-    
-    
-      
-    
-  
-
\ No newline at end of file
diff --git a/.idea/libraries/Maven__com_sun_jersey_jersey_atom_1_1_3_ea.xml b/.idea/libraries/Maven__com_sun_jersey_jersey_atom_1_1_3_ea.xml
deleted file mode 100644
index 12c5dff248..0000000000
--- a/.idea/libraries/Maven__com_sun_jersey_jersey_atom_1_1_3_ea.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-  
-    
-      
-    
-    
-      
-    
-    
-      
-    
-  
-
\ No newline at end of file
diff --git a/.idea/libraries/Maven__com_sun_jersey_jersey_client_1_1_3_ea.xml b/.idea/libraries/Maven__com_sun_jersey_jersey_client_1_1_3_ea.xml
deleted file mode 100644
index e9d1e118dd..0000000000
--- a/.idea/libraries/Maven__com_sun_jersey_jersey_client_1_1_3_ea.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-  
-    
-      
-    
-    
-      
-    
-    
-      
-    
-  
-
\ No newline at end of file
diff --git a/.idea/libraries/Maven__com_sun_jersey_jersey_core_1_1_3_ea.xml b/.idea/libraries/Maven__com_sun_jersey_jersey_core_1_1_3_ea.xml
deleted file mode 100644
index 4e6c2b7a08..0000000000
--- a/.idea/libraries/Maven__com_sun_jersey_jersey_core_1_1_3_ea.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-  
-    
-      
-    
-    
-      
-    
-    
-      
-    
-  
-
\ No newline at end of file
diff --git a/.idea/libraries/Maven__com_sun_jersey_jersey_json_1_1_3_ea.xml b/.idea/libraries/Maven__com_sun_jersey_jersey_json_1_1_3_ea.xml
deleted file mode 100644
index d6291c92a1..0000000000
--- a/.idea/libraries/Maven__com_sun_jersey_jersey_json_1_1_3_ea.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-  
-    
-      
-    
-    
-      
-    
-    
-      
-    
-  
-
\ No newline at end of file
diff --git a/.idea/libraries/Maven__com_sun_jersey_jersey_server_1_1_3_ea.xml b/.idea/libraries/Maven__com_sun_jersey_jersey_server_1_1_3_ea.xml
deleted file mode 100644
index 7d36a9900d..0000000000
--- a/.idea/libraries/Maven__com_sun_jersey_jersey_server_1_1_3_ea.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-  
-    
-      
-    
-    
-      
-    
-    
-      
-    
-  
-
\ No newline at end of file
diff --git a/.idea/libraries/Maven__com_sun_xml_bind_jaxb_impl_2_1_12.xml b/.idea/libraries/Maven__com_sun_xml_bind_jaxb_impl_2_1_12.xml
deleted file mode 100644
index fca2bf04c7..0000000000
--- a/.idea/libraries/Maven__com_sun_xml_bind_jaxb_impl_2_1_12.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-  
-    
-      
-    
-    
-      
-    
-    
-      
-    
-  
-
\ No newline at end of file
diff --git a/.idea/libraries/Maven__com_sun_xml_bind_jaxb_impl_2_1_6.xml b/.idea/libraries/Maven__com_sun_xml_bind_jaxb_impl_2_1_6.xml
deleted file mode 100644
index 6ce40cee86..0000000000
--- a/.idea/libraries/Maven__com_sun_xml_bind_jaxb_impl_2_1_6.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-  
-    
-      
-    
-    
-      
-    
-    
-      
-    
-  
-
\ No newline at end of file
diff --git a/.idea/libraries/Maven__commons_codec_commons_codec_1_3.xml b/.idea/libraries/Maven__commons_codec_commons_codec_1_3.xml
deleted file mode 100644
index 36880019d0..0000000000
--- a/.idea/libraries/Maven__commons_codec_commons_codec_1_3.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-  
-    
-      
-    
-    
-      
-    
-    
-      
-    
-  
-
\ No newline at end of file
diff --git a/.idea/libraries/Maven__commons_collections_commons_collections_3_2_1.xml b/.idea/libraries/Maven__commons_collections_commons_collections_3_2_1.xml
deleted file mode 100644
index 3caee7e547..0000000000
--- a/.idea/libraries/Maven__commons_collections_commons_collections_3_2_1.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-  
-    
-      
-    
-    
-      
-    
-    
-      
-    
-  
-
\ No newline at end of file
diff --git a/.idea/libraries/Maven__commons_fileupload_commons_fileupload_1_2_1.xml b/.idea/libraries/Maven__commons_fileupload_commons_fileupload_1_2_1.xml
deleted file mode 100644
index e59b3ef50c..0000000000
--- a/.idea/libraries/Maven__commons_fileupload_commons_fileupload_1_2_1.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-  
-    
-      
-    
-    
-      
-    
-    
-      
-    
-  
-
\ No newline at end of file
diff --git a/.idea/libraries/Maven__commons_httpclient_commons_httpclient_3_1.xml b/.idea/libraries/Maven__commons_httpclient_commons_httpclient_3_1.xml
deleted file mode 100644
index 66e653715c..0000000000
--- a/.idea/libraries/Maven__commons_httpclient_commons_httpclient_3_1.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-  
-    
-      
-    
-    
-      
-    
-    
-      
-    
-  
-
\ No newline at end of file
diff --git a/.idea/libraries/Maven__commons_io_commons_io_1_4.xml b/.idea/libraries/Maven__commons_io_commons_io_1_4.xml
deleted file mode 100644
index 054eda88ee..0000000000
--- a/.idea/libraries/Maven__commons_io_commons_io_1_4.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-  
-    
-      
-    
-    
-      
-    
-    
-      
-    
-  
-
\ No newline at end of file
diff --git a/.idea/libraries/Maven__commons_logging_commons_logging_1_0_4.xml b/.idea/libraries/Maven__commons_logging_commons_logging_1_0_4.xml
deleted file mode 100644
index 217d6e0a68..0000000000
--- a/.idea/libraries/Maven__commons_logging_commons_logging_1_0_4.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-  
-    
-      
-    
-    
-      
-    
-    
-      
-    
-  
-
\ No newline at end of file
diff --git a/.idea/libraries/Maven__commons_logging_commons_logging_api_1_1.xml b/.idea/libraries/Maven__commons_logging_commons_logging_api_1_1.xml
deleted file mode 100644
index 4b0a151519..0000000000
--- a/.idea/libraries/Maven__commons_logging_commons_logging_api_1_1.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-  
-    
-      
-    
-    
-      
-    
-    
-      
-    
-  
-
\ No newline at end of file
diff --git a/.idea/libraries/Maven__commons_pool_commons_pool_1_5_1.xml b/.idea/libraries/Maven__commons_pool_commons_pool_1_5_1.xml
deleted file mode 100644
index 095ea23bfa..0000000000
--- a/.idea/libraries/Maven__commons_pool_commons_pool_1_5_1.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-  
-    
-      
-    
-    
-      
-    
-    
-      
-    
-  
-
\ No newline at end of file
diff --git a/.idea/libraries/Maven__dispatch_http_dispatch_http_0_5_2.xml b/.idea/libraries/Maven__dispatch_http_dispatch_http_0_5_2.xml
deleted file mode 100644
index 762c91cb33..0000000000
--- a/.idea/libraries/Maven__dispatch_http_dispatch_http_0_5_2.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-  
-    
-      
-    
-    
-      
-    
-    
-      
-    
-  
-
\ No newline at end of file
diff --git a/.idea/libraries/Maven__dispatch_json_dispatch_json_0_5_2.xml b/.idea/libraries/Maven__dispatch_json_dispatch_json_0_5_2.xml
deleted file mode 100644
index 9a3c5acbeb..0000000000
--- a/.idea/libraries/Maven__dispatch_json_dispatch_json_0_5_2.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-  
-    
-      
-    
-    
-      
-    
-    
-      
-    
-  
-
\ No newline at end of file
diff --git a/.idea/libraries/Maven__javax_activation_activation_1_1.xml b/.idea/libraries/Maven__javax_activation_activation_1_1.xml
deleted file mode 100644
index 180d587561..0000000000
--- a/.idea/libraries/Maven__javax_activation_activation_1_1.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-  
-    
-      
-    
-    
-      
-    
-    
-      
-    
-  
-
\ No newline at end of file
diff --git a/.idea/libraries/Maven__javax_annotation_com_springsource_javax_annotation_1_0_0.xml b/.idea/libraries/Maven__javax_annotation_com_springsource_javax_annotation_1_0_0.xml
deleted file mode 100644
index e05ac5b518..0000000000
--- a/.idea/libraries/Maven__javax_annotation_com_springsource_javax_annotation_1_0_0.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-  
-    
-      
-    
-    
-      
-    
-    
-      
-    
-  
-
\ No newline at end of file
diff --git a/.idea/libraries/Maven__javax_annotation_jsr250_api_1_0.xml b/.idea/libraries/Maven__javax_annotation_jsr250_api_1_0.xml
deleted file mode 100644
index e367958818..0000000000
--- a/.idea/libraries/Maven__javax_annotation_jsr250_api_1_0.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-  
-    
-      
-    
-    
-      
-    
-    
-      
-    
-  
-
\ No newline at end of file
diff --git a/.idea/libraries/Maven__javax_mail_mail_1_4.xml b/.idea/libraries/Maven__javax_mail_mail_1_4.xml
deleted file mode 100644
index ead2b381a0..0000000000
--- a/.idea/libraries/Maven__javax_mail_mail_1_4.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-  
-    
-      
-    
-    
-      
-    
-    
-      
-    
-  
-
\ No newline at end of file
diff --git a/.idea/libraries/Maven__javax_servlet_servlet_api_2_5.xml b/.idea/libraries/Maven__javax_servlet_servlet_api_2_5.xml
deleted file mode 100644
index 679e09a1de..0000000000
--- a/.idea/libraries/Maven__javax_servlet_servlet_api_2_5.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-  
-    
-      
-    
-    
-      
-    
-    
-      
-    
-  
-
\ No newline at end of file
diff --git a/.idea/libraries/Maven__javax_ws_rs_jsr311_api_1_0.xml b/.idea/libraries/Maven__javax_ws_rs_jsr311_api_1_0.xml
deleted file mode 100644
index 646c50c102..0000000000
--- a/.idea/libraries/Maven__javax_ws_rs_jsr311_api_1_0.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-  
-    
-      
-    
-    
-      
-    
-    
-      
-    
-  
-
\ No newline at end of file
diff --git a/.idea/libraries/Maven__javax_ws_rs_jsr311_api_1_1.xml b/.idea/libraries/Maven__javax_ws_rs_jsr311_api_1_1.xml
deleted file mode 100644
index e412200bb5..0000000000
--- a/.idea/libraries/Maven__javax_ws_rs_jsr311_api_1_1.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-  
-    
-      
-    
-    
-      
-    
-    
-      
-    
-  
-
\ No newline at end of file
diff --git a/.idea/libraries/Maven__javax_xml_bind_jaxb_api_2_1.xml b/.idea/libraries/Maven__javax_xml_bind_jaxb_api_2_1.xml
deleted file mode 100644
index da3d0bf321..0000000000
--- a/.idea/libraries/Maven__javax_xml_bind_jaxb_api_2_1.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-  
-    
-      
-    
-    
-      
-    
-    
-      
-    
-  
-
\ No newline at end of file
diff --git a/.idea/libraries/Maven__javax_xml_stream_stax_api_1_0_2.xml b/.idea/libraries/Maven__javax_xml_stream_stax_api_1_0_2.xml
deleted file mode 100644
index 2a4dd7a2e5..0000000000
--- a/.idea/libraries/Maven__javax_xml_stream_stax_api_1_0_2.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-  
-    
-      
-    
-    
-      
-    
-    
-      
-    
-  
-
\ No newline at end of file
diff --git a/.idea/libraries/Maven__jdom_jdom_1_0.xml b/.idea/libraries/Maven__jdom_jdom_1_0.xml
deleted file mode 100644
index 3349d675fb..0000000000
--- a/.idea/libraries/Maven__jdom_jdom_1_0.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-  
-    
-      
-    
-    
-      
-    
-    
-      
-    
-  
-
\ No newline at end of file
diff --git a/.idea/libraries/Maven__junit_junit_4_4.xml b/.idea/libraries/Maven__junit_junit_4_4.xml
deleted file mode 100644
index 58e8c6d737..0000000000
--- a/.idea/libraries/Maven__junit_junit_4_4.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-  
-    
-      
-    
-    
-      
-    
-    
-      
-    
-  
-
\ No newline at end of file
diff --git a/.idea/libraries/Maven__junit_junit_4_5.xml b/.idea/libraries/Maven__junit_junit_4_5.xml
deleted file mode 100644
index 6ac8717594..0000000000
--- a/.idea/libraries/Maven__junit_junit_4_5.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-  
-    
-      
-    
-    
-      
-    
-    
-      
-    
-  
-
\ No newline at end of file
diff --git a/.idea/libraries/Maven__log4j_log4j_1_2_13.xml b/.idea/libraries/Maven__log4j_log4j_1_2_13.xml
deleted file mode 100644
index ccf6376b5f..0000000000
--- a/.idea/libraries/Maven__log4j_log4j_1_2_13.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-  
-    
-      
-    
-    
-      
-    
-    
-      
-    
-  
-
\ No newline at end of file
diff --git a/.idea/libraries/Maven__markdownj_markdownj_1_0_2b4_0_3_0.xml b/.idea/libraries/Maven__markdownj_markdownj_1_0_2b4_0_3_0.xml
deleted file mode 100644
index 994af6e0af..0000000000
--- a/.idea/libraries/Maven__markdownj_markdownj_1_0_2b4_0_3_0.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-  
-    
-      
-    
-    
-      
-    
-    
-      
-    
-  
-
\ No newline at end of file
diff --git a/.idea/libraries/Maven__net_lag_configgy_1_3.xml b/.idea/libraries/Maven__net_lag_configgy_1_3.xml
deleted file mode 100644
index 8f25f5555d..0000000000
--- a/.idea/libraries/Maven__net_lag_configgy_1_3.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-  
-    
-      
-    
-    
-      
-    
-    
-      
-    
-  
-
\ No newline at end of file
diff --git a/.idea/libraries/Maven__net_lag_configgy_1_4.xml b/.idea/libraries/Maven__net_lag_configgy_1_4.xml
deleted file mode 100644
index c300285bc9..0000000000
--- a/.idea/libraries/Maven__net_lag_configgy_1_4.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-  
-    
-      
-    
-    
-      
-    
-    
-      
-    
-  
-
\ No newline at end of file
diff --git a/.idea/libraries/Maven__net_liftweb_lift_util_1_1_M6.xml b/.idea/libraries/Maven__net_liftweb_lift_util_1_1_M6.xml
deleted file mode 100644
index 83f13a194e..0000000000
--- a/.idea/libraries/Maven__net_liftweb_lift_util_1_1_M6.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-  
-    
-      
-    
-    
-      
-    
-    
-      
-    
-  
-
\ No newline at end of file
diff --git a/.idea/libraries/Maven__org_aopalliance_com_springsource_org_aopalliance_1_0_0.xml b/.idea/libraries/Maven__org_aopalliance_com_springsource_org_aopalliance_1_0_0.xml
deleted file mode 100644
index 4df73cddc0..0000000000
--- a/.idea/libraries/Maven__org_aopalliance_com_springsource_org_aopalliance_1_0_0.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-  
-    
-      
-    
-    
-      
-    
-    
-      
-    
-  
-
\ No newline at end of file
diff --git a/.idea/libraries/Maven__org_apache_camel_camel_core_2_0_SNAPSHOT.xml b/.idea/libraries/Maven__org_apache_camel_camel_core_2_0_SNAPSHOT.xml
deleted file mode 100644
index c42c0f53c4..0000000000
--- a/.idea/libraries/Maven__org_apache_camel_camel_core_2_0_SNAPSHOT.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-  
-    
-      
-    
-    
-      
-    
-    
-      
-    
-  
-
\ No newline at end of file
diff --git a/.idea/libraries/Maven__org_apache_cassandra_cassandra_0_4_1.xml b/.idea/libraries/Maven__org_apache_cassandra_cassandra_0_4_1.xml
deleted file mode 100644
index 902d42a118..0000000000
--- a/.idea/libraries/Maven__org_apache_cassandra_cassandra_0_4_1.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-  
-    
-      
-    
-    
-      
-    
-    
-      
-    
-  
-
\ No newline at end of file
diff --git a/.idea/libraries/Maven__org_apache_zookeeper_3_1_0.xml b/.idea/libraries/Maven__org_apache_zookeeper_3_1_0.xml
deleted file mode 100644
index f722010be0..0000000000
--- a/.idea/libraries/Maven__org_apache_zookeeper_3_1_0.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-  
-    
-      
-    
-    
-      
-    
-    
-      
-    
-  
-
\ No newline at end of file
diff --git a/.idea/libraries/Maven__org_atmosphere_atmosphere_compat_0_4_1.xml b/.idea/libraries/Maven__org_atmosphere_atmosphere_compat_0_4_1.xml
deleted file mode 100644
index 94e9e1738a..0000000000
--- a/.idea/libraries/Maven__org_atmosphere_atmosphere_compat_0_4_1.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-  
-    
-      
-    
-    
-      
-    
-    
-      
-    
-  
-
\ No newline at end of file
diff --git a/.idea/libraries/Maven__org_atmosphere_atmosphere_core_0_4_SNAPSHOT.xml b/.idea/libraries/Maven__org_atmosphere_atmosphere_core_0_4_SNAPSHOT.xml
deleted file mode 100644
index 47978f54d8..0000000000
--- a/.idea/libraries/Maven__org_atmosphere_atmosphere_core_0_4_SNAPSHOT.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-  
-    
-      
-    
-    
-      
-    
-    
-      
-    
-  
-
\ No newline at end of file
diff --git a/.idea/libraries/Maven__org_atmosphere_atmosphere_portable_runtime_0_4_SNAPSHOT.xml b/.idea/libraries/Maven__org_atmosphere_atmosphere_portable_runtime_0_4_SNAPSHOT.xml
deleted file mode 100644
index d3cc2a5c99..0000000000
--- a/.idea/libraries/Maven__org_atmosphere_atmosphere_portable_runtime_0_4_SNAPSHOT.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-  
-    
-      
-    
-    
-      
-    
-    
-      
-    
-  
-
\ No newline at end of file
diff --git a/.idea/libraries/Maven__org_atmosphere_atmosphere_runtime_0_4_1.xml b/.idea/libraries/Maven__org_atmosphere_atmosphere_runtime_0_4_1.xml
deleted file mode 100644
index f8b8fa0593..0000000000
--- a/.idea/libraries/Maven__org_atmosphere_atmosphere_runtime_0_4_1.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-  
-    
-      
-    
-    
-      
-    
-    
-      
-    
-  
-
\ No newline at end of file
diff --git a/.idea/libraries/Maven__org_codehaus_aspectwerkz_aspectwerkz_jdk5_2_1.xml b/.idea/libraries/Maven__org_codehaus_aspectwerkz_aspectwerkz_jdk5_2_1.xml
deleted file mode 100644
index 9ebe0f9da4..0000000000
--- a/.idea/libraries/Maven__org_codehaus_aspectwerkz_aspectwerkz_jdk5_2_1.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-  
-    
-      
-    
-    
-      
-    
-    
-      
-    
-  
-
\ No newline at end of file
diff --git a/.idea/libraries/Maven__org_codehaus_aspectwerkz_aspectwerkz_nodeps_jdk5_2_1.xml b/.idea/libraries/Maven__org_codehaus_aspectwerkz_aspectwerkz_nodeps_jdk5_2_1.xml
deleted file mode 100644
index ed59cdf271..0000000000
--- a/.idea/libraries/Maven__org_codehaus_aspectwerkz_aspectwerkz_nodeps_jdk5_2_1.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-  
-    
-      
-    
-    
-      
-    
-    
-      
-    
-  
-
\ No newline at end of file
diff --git a/.idea/libraries/Maven__org_codehaus_jackson_jackson_core_asl_1_1_0.xml b/.idea/libraries/Maven__org_codehaus_jackson_jackson_core_asl_1_1_0.xml
deleted file mode 100644
index 84ed1b168b..0000000000
--- a/.idea/libraries/Maven__org_codehaus_jackson_jackson_core_asl_1_1_0.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-  
-    
-      
-    
-    
-      
-    
-    
-      
-    
-  
-
\ No newline at end of file
diff --git a/.idea/libraries/Maven__org_codehaus_jackson_jackson_mapper_asl_1_1_0.xml b/.idea/libraries/Maven__org_codehaus_jackson_jackson_mapper_asl_1_1_0.xml
deleted file mode 100644
index ac4a0caed1..0000000000
--- a/.idea/libraries/Maven__org_codehaus_jackson_jackson_mapper_asl_1_1_0.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-  
-    
-      
-    
-    
-      
-    
-    
-      
-    
-  
-
\ No newline at end of file
diff --git a/.idea/libraries/Maven__org_codehaus_jettison_jettison_1_1.xml b/.idea/libraries/Maven__org_codehaus_jettison_jettison_1_1.xml
deleted file mode 100644
index d62802e9c9..0000000000
--- a/.idea/libraries/Maven__org_codehaus_jettison_jettison_1_1.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-  
-    
-      
-    
-    
-      
-    
-    
-      
-    
-  
-
\ No newline at end of file
diff --git a/.idea/libraries/Maven__org_guiceyfruit_guice_all_2_0.xml b/.idea/libraries/Maven__org_guiceyfruit_guice_all_2_0.xml
deleted file mode 100644
index ef87273cd1..0000000000
--- a/.idea/libraries/Maven__org_guiceyfruit_guice_all_2_0.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-  
-    
-      
-    
-    
-      
-    
-    
-      
-    
-  
-
\ No newline at end of file
diff --git a/.idea/libraries/Maven__org_guiceyfruit_guice_core_2_0_beta_4.xml b/.idea/libraries/Maven__org_guiceyfruit_guice_core_2_0_beta_4.xml
deleted file mode 100644
index 1f70a76406..0000000000
--- a/.idea/libraries/Maven__org_guiceyfruit_guice_core_2_0_beta_4.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-  
-    
-      
-    
-    
-      
-    
-    
-      
-    
-  
-
\ No newline at end of file
diff --git a/.idea/libraries/Maven__org_guiceyfruit_guiceyfruit_core_2_0.xml b/.idea/libraries/Maven__org_guiceyfruit_guiceyfruit_core_2_0.xml
deleted file mode 100644
index 448d00f30f..0000000000
--- a/.idea/libraries/Maven__org_guiceyfruit_guiceyfruit_core_2_0.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-  
-    
-      
-    
-    
-      
-    
-    
-      
-    
-  
-
\ No newline at end of file
diff --git a/.idea/libraries/Maven__org_hamcrest_hamcrest_core_1_1.xml b/.idea/libraries/Maven__org_hamcrest_hamcrest_core_1_1.xml
deleted file mode 100644
index acdf44300b..0000000000
--- a/.idea/libraries/Maven__org_hamcrest_hamcrest_core_1_1.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-  
-    
-      
-    
-    
-      
-    
-    
-      
-    
-  
-
\ No newline at end of file
diff --git a/.idea/libraries/Maven__org_hamcrest_hamcrest_library_1_1.xml b/.idea/libraries/Maven__org_hamcrest_hamcrest_library_1_1.xml
deleted file mode 100644
index 010812aef6..0000000000
--- a/.idea/libraries/Maven__org_hamcrest_hamcrest_library_1_1.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-  
-    
-      
-    
-    
-      
-    
-    
-      
-    
-  
-
\ No newline at end of file
diff --git a/.idea/libraries/Maven__org_jboss_netty_netty_3_1_0_GA.xml b/.idea/libraries/Maven__org_jboss_netty_netty_3_1_0_GA.xml
deleted file mode 100644
index d98c601779..0000000000
--- a/.idea/libraries/Maven__org_jboss_netty_netty_3_1_0_GA.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-  
-    
-      
-    
-    
-      
-    
-    
-      
-    
-  
-
\ No newline at end of file
diff --git a/.idea/libraries/Maven__org_jmock_jmock_2_4_0.xml b/.idea/libraries/Maven__org_jmock_jmock_2_4_0.xml
deleted file mode 100644
index 92517ee4f8..0000000000
--- a/.idea/libraries/Maven__org_jmock_jmock_2_4_0.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-  
-    
-      
-    
-    
-      
-    
-    
-      
-    
-  
-
\ No newline at end of file
diff --git a/.idea/libraries/Maven__org_mockito_mockito_all_1_8_0.xml b/.idea/libraries/Maven__org_mockito_mockito_all_1_8_0.xml
deleted file mode 100644
index a5d0db7f09..0000000000
--- a/.idea/libraries/Maven__org_mockito_mockito_all_1_8_0.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-  
-    
-      
-    
-    
-      
-    
-    
-      
-    
-  
-
\ No newline at end of file
diff --git a/.idea/libraries/Maven__org_multiverse_multiverse_alpha_0_3_SNAPSHOT.xml b/.idea/libraries/Maven__org_multiverse_multiverse_alpha_0_3_SNAPSHOT.xml
deleted file mode 100644
index ce13287b16..0000000000
--- a/.idea/libraries/Maven__org_multiverse_multiverse_alpha_0_3_SNAPSHOT.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-  
-    
-      
-    
-    
-      
-    
-    
-      
-    
-  
-
\ No newline at end of file
diff --git a/.idea/libraries/Maven__org_multiverse_multiverse_core_0_3_SNAPSHOT.xml b/.idea/libraries/Maven__org_multiverse_multiverse_core_0_3_SNAPSHOT.xml
deleted file mode 100644
index 4ca9bc90c3..0000000000
--- a/.idea/libraries/Maven__org_multiverse_multiverse_core_0_3_SNAPSHOT.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-  
-    
-      
-    
-    
-      
-    
-    
-      
-    
-  
-
\ No newline at end of file
diff --git a/.idea/libraries/Maven__org_scala_lang_scala_compiler_2_7_4.xml b/.idea/libraries/Maven__org_scala_lang_scala_compiler_2_7_4.xml
deleted file mode 100644
index 03908a9b67..0000000000
--- a/.idea/libraries/Maven__org_scala_lang_scala_compiler_2_7_4.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-  
-    
-      
-    
-    
-      
-    
-    
-      
-    
-  
-
\ No newline at end of file
diff --git a/.idea/libraries/Maven__org_scala_lang_scala_compiler_2_7_5.xml b/.idea/libraries/Maven__org_scala_lang_scala_compiler_2_7_5.xml
deleted file mode 100644
index 193ab593bc..0000000000
--- a/.idea/libraries/Maven__org_scala_lang_scala_compiler_2_7_5.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-  
-    
-      
-    
-    
-      
-    
-    
-      
-    
-  
-
\ No newline at end of file
diff --git a/.idea/libraries/Maven__org_scala_lang_scala_library_2_7_5.xml b/.idea/libraries/Maven__org_scala_lang_scala_library_2_7_5.xml
deleted file mode 100644
index dacf0430aa..0000000000
--- a/.idea/libraries/Maven__org_scala_lang_scala_library_2_7_5.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-  
-    
-      
-    
-    
-      
-    
-    
-      
-    
-  
-
\ No newline at end of file
diff --git a/.idea/libraries/Maven__org_scala_tools_javautils_2_7_4_0_1.xml b/.idea/libraries/Maven__org_scala_tools_javautils_2_7_4_0_1.xml
deleted file mode 100644
index 4dfd1b7e3f..0000000000
--- a/.idea/libraries/Maven__org_scala_tools_javautils_2_7_4_0_1.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-  
-    
-      
-    
-    
-      
-    
-    
-      
-    
-  
-
\ No newline at end of file
diff --git a/.idea/libraries/Maven__org_scala_tools_testing_specs_1_4_4.xml b/.idea/libraries/Maven__org_scala_tools_testing_specs_1_4_4.xml
deleted file mode 100644
index 08d3c9ff24..0000000000
--- a/.idea/libraries/Maven__org_scala_tools_testing_specs_1_4_4.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-  
-    
-      
-    
-    
-      
-    
-    
-      
-    
-  
-
\ No newline at end of file
diff --git a/.idea/libraries/Maven__org_scala_tools_vscaladoc_1_1_md_3.xml b/.idea/libraries/Maven__org_scala_tools_vscaladoc_1_1_md_3.xml
deleted file mode 100644
index 56c052c8d3..0000000000
--- a/.idea/libraries/Maven__org_scala_tools_vscaladoc_1_1_md_3.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-  
-    
-      
-    
-    
-      
-    
-    
-      
-    
-  
-
\ No newline at end of file
diff --git a/.idea/libraries/Maven__org_scalatest_scalatest_1_0.xml b/.idea/libraries/Maven__org_scalatest_scalatest_1_0.xml
deleted file mode 100644
index a3c2487169..0000000000
--- a/.idea/libraries/Maven__org_scalatest_scalatest_1_0.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-  
-    
-      
-    
-    
-      
-    
-    
-      
-    
-  
-
\ No newline at end of file
diff --git a/.idea/libraries/Maven__org_slf4j_slf4j_api_1_4_3.xml b/.idea/libraries/Maven__org_slf4j_slf4j_api_1_4_3.xml
deleted file mode 100644
index 4649fc1238..0000000000
--- a/.idea/libraries/Maven__org_slf4j_slf4j_api_1_4_3.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-  
-    
-      
-    
-    
-      
-    
-    
-      
-    
-  
-
\ No newline at end of file
diff --git a/.idea/libraries/Maven__org_slf4j_slf4j_log4j12_1_4_3.xml b/.idea/libraries/Maven__org_slf4j_slf4j_log4j12_1_4_3.xml
deleted file mode 100644
index 98b791e7c9..0000000000
--- a/.idea/libraries/Maven__org_slf4j_slf4j_log4j12_1_4_3.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-  
-    
-      
-    
-    
-      
-    
-    
-      
-    
-  
-
\ No newline at end of file
diff --git a/.idea/libraries/Maven__rome_rome_0_9.xml b/.idea/libraries/Maven__rome_rome_0_9.xml
deleted file mode 100644
index 4821e96398..0000000000
--- a/.idea/libraries/Maven__rome_rome_0_9.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-  
-    
-      
-    
-    
-      
-    
-    
-      
-    
-  
-
\ No newline at end of file
diff --git a/.idea/libraries/Maven__sbinary_sbinary_0_3.xml b/.idea/libraries/Maven__sbinary_sbinary_0_3.xml
deleted file mode 100644
index a904098f21..0000000000
--- a/.idea/libraries/Maven__sbinary_sbinary_0_3.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-  
-    
-      
-    
-    
-      
-    
-    
-      
-    
-  
-
\ No newline at end of file
diff --git a/.idea/libraries/Maven__sjson_json_sjson_0_2.xml b/.idea/libraries/Maven__sjson_json_sjson_0_2.xml
deleted file mode 100644
index e6b0464e98..0000000000
--- a/.idea/libraries/Maven__sjson_json_sjson_0_2.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-  
-    
-      
-    
-    
-      
-    
-    
-      
-    
-  
-
\ No newline at end of file
diff --git a/.idea/libraries/Maven__stax_stax_api_1_0_1.xml b/.idea/libraries/Maven__stax_stax_api_1_0_1.xml
deleted file mode 100644
index 0b13335ee1..0000000000
--- a/.idea/libraries/Maven__stax_stax_api_1_0_1.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-  
-    
-      
-    
-    
-      
-    
-    
-      
-    
-  
-
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
deleted file mode 100644
index a9424288dd..0000000000
--- a/.idea/misc.xml
+++ /dev/null
@@ -1,73 +0,0 @@
-
-
-  
-    
-  
-    
-  
-    
-      
-        
-          
-        
-      
-    
-  
-  
-  
-    
-  
-    
-    
-  
-  
-    
-  
-    
-  
-    
-  
-  
-    
-  
-  
-    
-  
-  
-    
-    
-  
-
-
diff --git a/.idea/modules.xml b/.idea/modules.xml
deleted file mode 100644
index 891ba469c7..0000000000
--- a/.idea/modules.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-
-
-  
-    
-      
-      
-      
-      
-      
-      
-      
-      
-      
-      
-      
-      
-      
-      
-      
-    
-  
-
-
diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml
deleted file mode 100644
index 3b00020308..0000000000
--- a/.idea/uiDesigner.xml
+++ /dev/null
@@ -1,125 +0,0 @@
-
-
-  
-    
-      
-        
-      
-      
-        
-      
-      
-        
-      
-      
-        
-      
-      
-        
-        
-          
-        
-      
-      
-        
-        
-          
-        
-      
-      
-        
-        
-          
-        
-      
-      
-        
-        
-          
-        
-      
-      
-        
-          
-        
-      
-      
-        
-          
-        
-      
-      
-        
-          
-        
-      
-      
-        
-          
-        
-      
-      
-        
-          
-        
-      
-      
-        
-          
-        
-      
-      
-        
-      
-      
-        
-          
-        
-      
-      
-        
-          
-        
-      
-      
-        
-          
-        
-      
-      
-        
-          
-        
-      
-      
-        
-          
-        
-      
-      
-        
-      
-      
-        
-      
-      
-        
-      
-      
-        
-      
-      
-        
-          
-        
-      
-      
-        
-      
-      
-        
-      
-    
-  
-
-
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
deleted file mode 100644
index 9d32e507a9..0000000000
--- a/.idea/vcs.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-  
-    
-    
-  
-
-
diff --git a/.idea/workspace.xml b/.idea/workspace.xml
deleted file mode 100644
index 0dc072b32f..0000000000
--- a/.idea/workspace.xml
+++ /dev/null
@@ -1,638 +0,0 @@
-
-
-  
-    
-      
-      
-      
-      
-      
-      
-      
-      
-      
-      
-      
-      
-      
-      
-      
-      
-      
-      
-      
-      
-      
-      
-      
-      
-      
-      
-      
-      
-      
-      
-      
-      
-      
-      
-      
-      
-      
-      
-      
-      
-      
-      
-      
-      
-      
-      
-      
-      
-      
-      
-      
-    
-    
-    
-    
-  
-  
-    
-  
-    
-  
-  
-    
-      
-        
-      
-        
-    
-    
-    
-  
-  
-    
-  
-  
-  
-    
-      
-        
-          
-            
-              
-            
-          
-        
-      
-      
-        
-          
-            
-              
-            
-          
-        
-      
-      
-        
-          
-            
-              
-            
-          
-        
-      
-      
-        
-          
-            
-              
-            
-          
-        
-      
-      
-        
-          
-            
-              
-            
-          
-        
-      
-      
-        
-          
-            
-              
-            
-          
-        
-      
-      
-        
-          
-            
-              
-            
-          
-        
-      
-      
-        
-          
-            
-              
-            
-          
-        
-      
-      
-        
-          
-            
-              
-            
-          
-        
-      
-      
-        
-          
-            
-              
-            
-          
-        
-      
-    
-  
-  
-    
-      
-    
-  
-  
-    
-  
-  
-    
-  
-  
-    
-  
-    
-      
-    
-  
-  
-    
-    
-    
-    
-    
-    
-    
-    
-  
-  
-    
-  
-    
-      
-      
-      
-      
-      
-      
-      
-      
-      
-    
-    
-      
-      
-      
-        
-          
-            
-              
-          
-        
-      
-      
-    
-  
-  
-    
-    
-    
-    
-    
-    
-    
-    
-    
-    
-  
-  
-    
-      
-    
-      
-        
-    
-    
-      
-      
-    
-      
-      
-      
-      
-      
-      
-        
-    
-    
-      
-      
-      
-    
-    
-      localhost
-      5050
-    
-  
-  
-  
-    
-  
-    
-      
-      1258488323388
-      1258488323388
-    
-  
-  
-    
-    
-    
-      
-      
-      
-      
-      
-      
-      
-      
-      
-      
-      
-      
-      
-      
-      
-      
-      
-      
-      
-      
-    
-  
-  
-    
-  
-    
-  
-  
-    
-      
-        
-          
-        
-      
-    
-    
-      
-        
-          
-        
-      
-    
-    
-      
-        
-          
-        
-      
-    
-    
-      
-        
-          
-            
-          
-        
-      
-    
-    
-      
-        
-          
-        
-      
-    
-    
-      
-        
-          
-        
-      
-    
-    
-      
-        
-          
-        
-      
-    
-    
-      
-        
-          
-        
-      
-    
-    
-      
-        
-          
-        
-      
-    
-    
-      
-        
-          
-        
-      
-    
-    
-      
-        
-          
-        
-      
-    
-    
-      
-        
-          
-        
-      
-    
-    
-      
-        
-          
-        
-      
-    
-    
-      
-        
-          
-        
-      
-    
-    
-      
-        
-          
-        
-      
-    
-    
-      
-        
-          
-        
-      
-    
-  
-  
-    
-      
-        
-          
-            
-              
-            
-          
-          
-        
-      
-      
-        
-          
-            
-          
-        
-      
-      
-        
-          
-            
-              
-            
-          
-          1.6
-        
-      
-      
-        
-          
-            
-          
-          
-        
-      
-    
-  
-
-

From b1c1c0794769c57c5a1a2c6debe1bf518a8fe949 Mon Sep 17 00:00:00 2001
From: jboner 
Date: Fri, 20 Nov 2009 11:12:03 +0100
Subject: [PATCH 03/20] added stop method to actor

---
 akka-actors/src/main/scala/actor/Actor.scala  |  8 ++++-
 .../src/main/scala/actor/Supervisor.scala     | 30 +++++++++----------
 .../EventBasedSingleThreadActorTest.scala     |  8 ++---
 .../scala/EventBasedThreadPoolActorTest.scala |  8 ++---
 .../src/test/scala/RemoteActorTest.scala      |  8 ++---
 .../src/test/scala/SchedulerTest.scala        |  2 +-
 .../src/test/scala/ThreadBasedActorTest.scala |  8 ++---
 akka-amqp/src/main/scala/AMQP.scala           |  2 +-
 .../src/main/scala/SimpleService.scala        |  2 +-
 9 files changed, 40 insertions(+), 36 deletions(-)

diff --git a/akka-actors/src/main/scala/actor/Actor.scala b/akka-actors/src/main/scala/actor/Actor.scala
index 5aba208a28..4f63d8aa26 100644
--- a/akka-actors/src/main/scala/actor/Actor.scala
+++ b/akka-actors/src/main/scala/actor/Actor.scala
@@ -283,8 +283,14 @@ trait Actor extends Logging with TransactionManagement {
 
   /**
    * Shuts down the actor its dispatcher and message queue.
+   * Delegates to 'stop'
    */
-  def exit = synchronized {
+  protected def exit = stop
+
+  /**
+   * Shuts down the actor its dispatcher and message queue.
+   */
+  def stop = synchronized {
     if (_isRunning) {
       messageDispatcher.unregisterHandler(this)
       if (messageDispatcher.isInstanceOf[ThreadBasedDispatcher]) messageDispatcher.shutdown
diff --git a/akka-actors/src/main/scala/actor/Supervisor.scala b/akka-actors/src/main/scala/actor/Supervisor.scala
index d08150364e..1dadd2cdac 100644
--- a/akka-actors/src/main/scala/actor/Supervisor.scala
+++ b/akka-actors/src/main/scala/actor/Supervisor.scala
@@ -106,26 +106,24 @@ sealed class Supervisor private[akka] (handler: FaultHandlingStrategy)
   override def start = {
     ConfiguratorRepository.registerConfigurator(this)
     actors.values.toArray.toList.foreach(println)
+    _linkedActors.toArray.toList.asInstanceOf[List[Actor]].foreach { actor =>
+      actor.start
+      log.info("Starting actor: %s", actor)
+    }
     super[Actor].start
-    this ! StartSupervisor
   }
   
-  def stop = this !? StopSupervisor
+  override def stop = {
+    super[Actor].stop
+    _linkedActors.toArray.toList.asInstanceOf[List[Actor]].foreach { actor =>
+      actor.stop
+      log.info("Shutting actor down: %s", actor)
+    }
+    log.info("Stopping supervisor: %s", this)
+  }
 
-  protected def receive = {
-    case StartSupervisor =>
-      _linkedActors.toArray.toList.asInstanceOf[List[Actor]].foreach { actor =>
-        actor.start
-        log.info("Starting actor: %s", actor)
-      }
-
-    case StopSupervisor =>
-      _linkedActors.toArray.toList.asInstanceOf[List[Actor]].foreach { actor =>
-        actor.exit
-        log.info("Shutting actor down: %s", actor)
-      }
-      log.info("Stopping supervisor: %s", this)
-      exit
+  def receive = {
+    case _ => throw new IllegalArgumentException("Supervisor does not respond to any messages")
   }
 
   def configure(config: SupervisorConfig, factory: SupervisorFactory) = config match {
diff --git a/akka-actors/src/test/scala/EventBasedSingleThreadActorTest.scala b/akka-actors/src/test/scala/EventBasedSingleThreadActorTest.scala
index fd9e20e95c..67fbf89da8 100644
--- a/akka-actors/src/test/scala/EventBasedSingleThreadActorTest.scala
+++ b/akka-actors/src/test/scala/EventBasedSingleThreadActorTest.scala
@@ -33,7 +33,7 @@ class EventBasedSingleThreadActorTest extends JUnitSuite {
     val result = actor ! "OneWay"
     Thread.sleep(100)
     assert("received" === oneWay)
-    actor.exit
+    actor.stop
   }
 
   @Test def shouldSendReplySync = {
@@ -42,7 +42,7 @@ class EventBasedSingleThreadActorTest extends JUnitSuite {
     actor.start
     val result: String = actor !? "Hello"
     assert("World" === result)
-    actor.exit
+    actor.stop
   }
 
   @Test def shouldSendReplyAsync = {
@@ -51,7 +51,7 @@ class EventBasedSingleThreadActorTest extends JUnitSuite {
     actor.start
     val result = actor !! "Hello"
     assert("World" === result.get.asInstanceOf[String])
-    actor.exit
+    actor.stop
   }
 
   @Test def shouldSendReceiveException = {
@@ -65,6 +65,6 @@ class EventBasedSingleThreadActorTest extends JUnitSuite {
       case e =>
         assert("expected" === e.getMessage())
     }
-    actor.exit
+    actor.stop
   }
 }
diff --git a/akka-actors/src/test/scala/EventBasedThreadPoolActorTest.scala b/akka-actors/src/test/scala/EventBasedThreadPoolActorTest.scala
index b6747a9119..e82784cc67 100644
--- a/akka-actors/src/test/scala/EventBasedThreadPoolActorTest.scala
+++ b/akka-actors/src/test/scala/EventBasedThreadPoolActorTest.scala
@@ -29,7 +29,7 @@ class EventBasedThreadPoolActorTest extends JUnitSuite {
     val result = actor ! "OneWay"
     Thread.sleep(100)
     assert("received" === oneWay)
-    actor.exit
+    actor.stop
   }
 
   @Test def shouldSendReplySync = {
@@ -38,7 +38,7 @@ class EventBasedThreadPoolActorTest extends JUnitSuite {
     actor.start
     val result: String = actor !? "Hello"
     assert("World" === result)
-    actor.exit
+    actor.stop
   }
 
   @Test def shouldSendReplyAsync = {
@@ -47,7 +47,7 @@ class EventBasedThreadPoolActorTest extends JUnitSuite {
     actor.start
     val result = actor !! "Hello"
     assert("World" === result.get.asInstanceOf[String])
-    actor.exit
+    actor.stop
   }
 
   @Test def shouldSendReceiveException = {
@@ -61,6 +61,6 @@ class EventBasedThreadPoolActorTest extends JUnitSuite {
       case e =>
         assert("expected" === e.getMessage())
     }
-    actor.exit
+    actor.stop
   }
 }
diff --git a/akka-actors/src/test/scala/RemoteActorTest.scala b/akka-actors/src/test/scala/RemoteActorTest.scala
index 447ada87f6..1b6cb5bd76 100644
--- a/akka-actors/src/test/scala/RemoteActorTest.scala
+++ b/akka-actors/src/test/scala/RemoteActorTest.scala
@@ -46,7 +46,7 @@ class RemoteActorTest extends JUnitSuite   {
     val result = actor ! "OneWay"
     Thread.sleep(100)
     assert("received" === Global.oneWay)
-    actor.exit
+    actor.stop
   }
 
   @Test
@@ -57,7 +57,7 @@ class RemoteActorTest extends JUnitSuite   {
     actor.start
     val result: String = actor !? "Hello"
     assert("World" === result)
-    actor.exit
+    actor.stop
   }
 
   @Test
@@ -68,7 +68,7 @@ class RemoteActorTest extends JUnitSuite   {
     actor.start
     val result = actor !! "Hello"
     assert("World" === result.get.asInstanceOf[String])
-    actor.exit
+    actor.stop
   }
 
   @Test
@@ -84,6 +84,6 @@ class RemoteActorTest extends JUnitSuite   {
       case e =>
         assert("expected" === e.getMessage())
     }
-    actor.exit
+    actor.stop
   }
 }
diff --git a/akka-actors/src/test/scala/SchedulerTest.scala b/akka-actors/src/test/scala/SchedulerTest.scala
index 389fba7012..383e1f5206 100644
--- a/akka-actors/src/test/scala/SchedulerTest.scala
+++ b/akka-actors/src/test/scala/SchedulerTest.scala
@@ -18,7 +18,7 @@ class SchedulerTest extends JUnitSuite {
     Thread.sleep(1000)
     Scheduler.schedule(actor, Tick, 0L, 1L, TimeUnit.SECONDS)
     Thread.sleep(5000)
-    Scheduler.shutdown
+    Scheduler.stop
     assert(count > 0)
   }
 }
\ No newline at end of file
diff --git a/akka-actors/src/test/scala/ThreadBasedActorTest.scala b/akka-actors/src/test/scala/ThreadBasedActorTest.scala
index 56762a7321..e39b9322f1 100644
--- a/akka-actors/src/test/scala/ThreadBasedActorTest.scala
+++ b/akka-actors/src/test/scala/ThreadBasedActorTest.scala
@@ -33,7 +33,7 @@ class ThreadBasedActorTest extends JUnitSuite {
     val result = actor ! "OneWay"
     Thread.sleep(100)
     assert("received" === oneWay)
-    actor.exit
+    actor.stop
   }
 
   @Test def shouldSendReplySync = {
@@ -42,7 +42,7 @@ class ThreadBasedActorTest extends JUnitSuite {
     actor.start
     val result: String = actor !? "Hello"
     assert("World" === result)
-    actor.exit
+    actor.stop
   }
 
   @Test def shouldSendReplyAsync = {
@@ -51,7 +51,7 @@ class ThreadBasedActorTest extends JUnitSuite {
     actor.start
     val result = actor !! "Hello"
     assert("World" === result.get.asInstanceOf[String])
-    actor.exit
+    actor.stop
   }
 
   @Test def shouldSendReceiveException = {
@@ -65,6 +65,6 @@ class ThreadBasedActorTest extends JUnitSuite {
       case e =>
         assert("expected" === e.getMessage())
     }
-    actor.exit
+    actor.stop
   }
 }
diff --git a/akka-amqp/src/main/scala/AMQP.scala b/akka-amqp/src/main/scala/AMQP.scala
index 0c2376a905..3143f41ee6 100644
--- a/akka-amqp/src/main/scala/AMQP.scala
+++ b/akka-amqp/src/main/scala/AMQP.scala
@@ -401,7 +401,7 @@ object AMQP extends Actor {
             case Some(tag) =>
               channel.basicCancel(tag)
               unlink(listener.actor)
-              listener.actor.exit
+              listener.actor.stop
               log.debug("Message consumer is cancelled and shut down [%s]", listener)
           }
       }
diff --git a/akka-samples-security/src/main/scala/SimpleService.scala b/akka-samples-security/src/main/scala/SimpleService.scala
index a0950a2f38..cca4246933 100644
--- a/akka-samples-security/src/main/scala/SimpleService.scala
+++ b/akka-samples-security/src/main/scala/SimpleService.scala
@@ -33,7 +33,7 @@ class Boot {
 
 
   val supervisor = factory.newInstance
-  supervisor.start
+ supervisor.start
 }
 
 /*

From 11a38c7c8dc738b4b70dd9d5f91e7621d83cf668 Mon Sep 17 00:00:00 2001
From: jboner 
Date: Sat, 21 Nov 2009 19:34:42 +0100
Subject: [PATCH 04/20] Cleaned up the Actor and Supervisor classes. Added
 implicit sender to actor ! methods, works with 'sender' field and 'reply'

---
 .../src/main/scala/actor/ActiveObject.scala   |   2 +
 akka-actors/src/main/scala/actor/Actor.scala  | 202 ++++++++++++------
 .../src/main/scala/actor/Scheduler.scala      |   2 +-
 .../src/main/scala/actor/Supervisor.scala     |  28 +--
 .../src/main/scala/dispatch/Dispatchers.scala |   4 +-
 .../src/main/scala/dispatch/Reactor.scala     |   7 +-
 .../src/main/scala/nio/RemoteClient.scala     |   1 +
 .../src/main/scala/nio/RemoteServer.scala     |   1 +
 .../src/main/scala/stm/DataFlowVariable.scala |  12 +-
 .../ActorFireForgetRequestReplyTest.scala     |  51 +++++
 .../EventBasedSingleThreadActorTest.scala     |   1 +
 ...EventBasedSingleThreadDispatcherTest.scala |  10 +-
 .../scala/EventBasedThreadPoolActorTest.scala |   1 +
 .../EventBasedThreadPoolDispatcherTest.scala  |  14 +-
 .../src/test/scala/RemoteActorTest.scala      |   1 +
 .../src/test/scala/RemoteSupervisorTest.scala |  37 ++--
 .../src/test/scala/SupervisorTest.scala       |  37 ++--
 .../src/test/scala/ThreadBasedActorTest.scala |   1 +
 .../scala/ThreadBasedDispatcherTest.scala     |   4 +-
 akka-amqp/src/main/scala/AMQP.scala           |   8 +-
 akka-util/src/main/scala/Config.scala         |  15 +-
 changes.xml                                   |   7 +
 22 files changed, 288 insertions(+), 158 deletions(-)
 create mode 100644 akka-actors/src/test/scala/ActorFireForgetRequestReplyTest.scala

diff --git a/akka-actors/src/main/scala/actor/ActiveObject.scala b/akka-actors/src/main/scala/actor/ActiveObject.scala
index dd14cda0a5..983d323148 100644
--- a/akka-actors/src/main/scala/actor/ActiveObject.scala
+++ b/akka-actors/src/main/scala/actor/ActiveObject.scala
@@ -160,6 +160,8 @@ private[akka] sealed case class AspectInit(
  */
 @Aspect("perInstance")
 private[akka] sealed class ActiveObjectAspect {
+  import Actor._
+  
   @volatile var isInitialized = false
   var target: Class[_] = _
   var actor: Dispatcher = _            
diff --git a/akka-actors/src/main/scala/actor/Actor.scala b/akka-actors/src/main/scala/actor/Actor.scala
index 4f63d8aa26..de1cb5fba6 100644
--- a/akka-actors/src/main/scala/actor/Actor.scala
+++ b/akka-actors/src/main/scala/actor/Actor.scala
@@ -23,15 +23,22 @@ import org.codehaus.aspectwerkz.proxy.Uuid
 
 import org.multiverse.utils.ThreadLocalTransaction._
 
-@serializable sealed abstract class LifeCycleMessage
+/**
+ * Mix in this trait to give an actor TransactionRequired semantics.
+ * Equivalent to invoking the 'makeTransactionRequired' method in the actor.  
+ */
+trait TransactionRequired { this: Actor =>
+  makeTransactionRequired  
+}
+
+@serializable sealed trait LifeCycleMessage
 case class Init(config: AnyRef) extends LifeCycleMessage
 case class HotSwap(code: Option[PartialFunction[Any, Unit]]) extends LifeCycleMessage
 case class Restart(reason: AnyRef) extends LifeCycleMessage
 case class Exit(dead: Actor, killer: Throwable) extends LifeCycleMessage
-case class Kill(killer: Actor) extends LifeCycleMessage
-//case object TransactionalInit extends LifeCycleMessage
+case object Kill extends LifeCycleMessage
 
-class ActorKilledException(val killed: Actor, val killer: Actor) extends RuntimeException("Actor [" + killed + "] killed by [" + killer + "]")
+class ActorKilledException(val killed: Actor) extends RuntimeException("Actor [" + killed + "] was killed by a Kill message")
 
 sealed abstract class DispatcherType
 object DispatcherType {
@@ -55,13 +62,21 @@ object Actor {
   val TIMEOUT = config.getInt("akka.actor.timeout", 5000)
   val SERIALIZE_MESSAGES = config.getBool("akka.actor.serialize-messages", false)
 
+  implicit val any: AnyRef = this  
+
   def actor(body: PartialFunction[Any, Unit]): Actor = new Actor() {
     start
     def receive = body
   }
 
+  def actor(body: => Unit)(matcher: PartialFunction[Any, Unit]): Actor = new Actor() {
+    start
+    body
+    def receive = matcher
+  }
+
   def actor(lifeCycleConfig: LifeCycle)(body: PartialFunction[Any, Unit]): Actor = new Actor() {
-    lifeCycle = Some(lifeCycleConfig)
+    lifeCycle = lifeCycleConfig
     start
     def receive = body
   }
@@ -82,12 +97,17 @@ object Actor {
  */
 trait Actor extends Logging with TransactionManagement {
   ActorRegistry.register(this)
+
+  implicit val self: AnyRef = this
   
   // FIXME http://www.assembla.com/spaces/akka/tickets/56-Change-UUID-generation-for-the-TransactionManagement-trait
   val uuid = Uuid.newUuid.toString
 
+  // ====================================
   // private fields
-  @volatile private var _isRunning: Boolean = false
+  // ====================================
+
+   @volatile private var _isRunning: Boolean = false
   @volatile private var _isShutDown: Boolean = false
   private var _hotswap: Option[PartialFunction[Any, Unit]] = None
   private var _config: Option[AnyRef] = None
@@ -97,12 +117,28 @@ trait Actor extends Logging with TransactionManagement {
   private[akka] var _mailbox: MessageQueue = _
   private[akka] var _supervisor: Option[Actor] = None
 
+  // ====================================
+  // protected fields
+  // ====================================
+
   /**
-   * This field should normally not be touched by user code, which should instead use the 'reply' method.
+   * The 'sender' field holds the sender of the message currently being processed.
+   * 

+ * If the sender was an actor then it is defined as 'Some(senderActor)' and + * if the sender was of some other instance then it is defined as 'None'. + *

+ * This sender reference can be used together with the '!' method for request/reply + * message exchanges and which is in many ways better than using the '!!' method + * which will make the sender wait for a reply using a *blocking* future. + */ + protected[this] var sender: Option[Actor] = None + + /** + * The 'senderFuture' field should normally not be touched by user code, which should instead use the 'reply' method. * But it can be used for advanced use-cases when one might want to store away the future and * resolve it later and/or somewhere else. */ - protected var senderFuture: Option[CompletableFutureResult] = None + protected[this] var senderFuture: Option[CompletableFutureResult] = None // ==================================== // ==== USER CALLBACKS TO OVERRIDE ==== @@ -127,30 +163,19 @@ trait Actor extends Logging with TransactionManagement { /** * User overridable callback/setting. - * - * User can (and is encouraged to) override the default configuration (newEventBasedThreadPoolDispatcher) - * so it fits the specific use-case that the actor is used for. *

- * It is beneficial to have actors share the same dispatcher, easily +100 actors can share the same. + * The default dispatcher is the Dispatchers.globalEventBasedThreadPoolDispatcher. + * This means that all actors will share the same event-driven thread-pool based dispatcher. *

- * But if you are running many many actors then it can be a good idea to have split them up in terms of - * dispatcher sharing. + * You can override it so it fits the specific use-case that the actor is used for. + * See the se.scalablesolutions.akka.dispatch.Dispatchers class for the different + * dispatchers available. *

- * Default is that all actors that are created and spawned from within this actor is sharing the same - * dispatcher as its creator. - *

-   *   val dispatcher = Dispatchers.newEventBasedThreadPoolDispatcher
-   *   dispatcher
-   *     .withNewThreadPoolWithBoundedBlockingQueue(100)
-   *     .setCorePoolSize(16)
-   *     .setMaxPoolSize(128)
-   *     .setKeepAliveTimeInMillis(60000)
-   *     .setRejectionPolicy(new CallerRunsPolicy)
-   *     .buildThreadPool
-   * 
+ * The default is also that all actors that are created and spawned from within this actor + * is sharing the same dispatcher as its creator. */ protected[akka] var messageDispatcher: MessageDispatcher = { - val dispatcher = Dispatchers.newEventBasedThreadPoolDispatcher(getClass.getName) + val dispatcher = Dispatchers.globalEventBasedThreadPoolDispatcher _mailbox = dispatcher.messageQueue dispatcher } @@ -190,7 +215,7 @@ trait Actor extends Logging with TransactionManagement { * * Defines the life-cycle for a supervised actor. Default is 'LifeCycle(Permanent)' but can be overridden. */ - @volatile var lifeCycle: Option[LifeCycle] = Some(LifeCycle(Permanent)) + @volatile var lifeCycle: LifeCycle = LifeCycle(Permanent) /** * User overridable callback/setting. @@ -270,7 +295,7 @@ trait Actor extends Logging with TransactionManagement { /** * Starts up the actor and its message queue. */ - def start = synchronized { + def start: Actor = synchronized { if (_isShutDown) throw new IllegalStateException("Can't restart an actor that have been shut down with 'exit'") if (!_isRunning) { dispatcher.registerHandler(this, new ActorMessageInvoker(this)) @@ -279,6 +304,7 @@ trait Actor extends Logging with TransactionManagement { //if (isTransactional) this !! TransactionalInit } log.info("[%s] has started", toString) + this } /** @@ -303,10 +329,28 @@ trait Actor extends Logging with TransactionManagement { /** * Sends a one-way asynchronous message. E.g. fire-and-forget semantics. + *

+ * If invoked from within an actor then the actor reference is implicitly passed on as the implicit 'sender' argument. + * This actor 'sender' reference is then available in the receiving actor in the 'sender' member variable. + *

+ * If invoked from within another object then add this import to resolve the implicit argument: + *

+   * import se.scalablesolutions.akka.actor.Actor._
+   * 
*/ - def !(message: AnyRef) = - if (_isRunning) postMessageToMailbox(message) - else throw new IllegalStateException("Actor has not been started, you need to invoke 'actor.start' before using it") + def !(message: AnyRef)(implicit sender: AnyRef) = { + val from = if (sender != null && sender.isInstanceOf[Actor]) Some(sender.asInstanceOf[Actor]) + else None + if (_isRunning) postMessageToMailbox(message, from) + else throw new IllegalStateException( + "Actor has not been started, you need to invoke 'actor.start' before using it") + } + + def send(message: AnyRef) = { + if (_isRunning) postMessageToMailbox(message, None) + else throw new IllegalStateException( + "Actor has not been started, you need to invoke 'actor.start' before using it") + } /** * Sends a message asynchronously and waits on a future for a reply message. @@ -315,6 +359,8 @@ trait Actor extends Logging with TransactionManagement { * or until the timeout expires (which will return None). E.g. send-and-receive-eventually semantics. *

* NOTE: + * Use this method with care. In most cases it is better to use '!' together with the 'sender' member field to + * implement request/response message exchanges. * If you are sending messages using !! then you have to use reply(..) * to send a reply message to the original sender. If not then the sender will block until the timeout expires. */ @@ -330,7 +376,8 @@ trait Actor extends Logging with TransactionManagement { else None } getResultOrThrowException(future) - } else throw new IllegalStateException("Actor has not been started, you need to invoke 'actor.start' before using it") + } else throw new IllegalStateException( + "Actor has not been started, you need to invoke 'actor.start' before using it") /** * Sends a message asynchronously and waits on a future for a reply message. @@ -339,6 +386,8 @@ trait Actor extends Logging with TransactionManagement { * or until the timeout expires (which will return None). E.g. send-and-receive-eventually semantics. *

* NOTE: + * Use this method with care. In most cases it is better to use '!' together with the 'sender' member field to + * implement request/response message exchanges. * If you are sending messages using !! then you have to use reply(..) * to send a reply message to the original sender. If not then the sender will block until the timeout expires. */ @@ -354,22 +403,31 @@ trait Actor extends Logging with TransactionManagement { val future = postMessageToMailboxAndCreateFutureResultWithTimeout(message, 0) future.awaitBlocking getResultOrThrowException(future).get - } else throw new IllegalStateException("Actor has not been started, you need to invoke 'actor.start' before using it") + } else throw new IllegalStateException( + "Actor has not been started, you need to invoke 'actor.start' before using it") /** * Use reply(..) to reply with a message to the original sender of the message currently * being processed. - *

- * NOTE: - * Does only work together with the actor !! method and/or active objects not annotated - * with @oneway. */ - protected[this] def reply(message: AnyRef) = senderFuture match { - case None => throw new IllegalStateException( - "\n\tNo sender in scope, can't reply. " + - "\n\tHave you used the '!' message send or the '@oneway' active object annotation? " + - "\n\tIf so, switch to '!!' (or remove '@oneway') which passes on an implicit future that will be bound by the argument passed to 'reply'." ) - case Some(future) => future.completeWithResult(message) + protected[this] def reply(message: AnyRef) = { + sender match { + case Some(senderActor) => + senderActor ! message + case None => + senderFuture match { + case None => + throw new IllegalStateException( + "\n\tNo sender in scope, can't reply. " + + "\n\tYou have probably used the '!' method to either; " + + "\n\t\t1. Send a message to a remote actor" + + "\n\t\t2. Send a message from an instance that is *not* an actor" + + "\n\t\t3. Send a message to an Active Object annotated with the '@oneway' annotation? " + + "\n\tIf so, switch to '!!' (or remove '@oneway') which passes on an implicit future that will be bound by the argument passed to 'reply'." ) + case Some(future) => + future.completeWithResult(message) + } + } } /** @@ -385,7 +443,8 @@ trait Actor extends Logging with TransactionManagement { messageDispatcher = dispatcher _mailbox = messageDispatcher.messageQueue messageDispatcher.registerHandler(this, new ActorMessageInvoker(this)) - } else throw new IllegalArgumentException("Can not swap dispatcher for " + toString + " after it has been started") + } else throw new IllegalArgumentException( + "Can not swap dispatcher for " + toString + " after it has been started") } /** @@ -411,7 +470,8 @@ trait Actor extends Logging with TransactionManagement { *

*/ def makeTransactionRequired = synchronized { - if (_isRunning) throw new IllegalArgumentException("Can not make actor transaction required after it has been started") + if (_isRunning) throw new IllegalArgumentException( + "Can not make actor transaction required after it has been started") else isTransactionRequiresNew = true } @@ -428,10 +488,12 @@ trait Actor extends Logging with TransactionManagement { protected[this] def link(actor: Actor) = { if (_isRunning) { _linkedActors.add(actor) - if (actor._supervisor.isDefined) throw new IllegalStateException("Actor can only have one supervisor [" + actor + "], e.g. link(actor) fails") + if (actor._supervisor.isDefined) throw new IllegalStateException( + "Actor can only have one supervisor [" + actor + "], e.g. link(actor) fails") actor._supervisor = Some(this) log.debug("Linking actor [%s] to actor [%s]", actor, this) - } else throw new IllegalStateException("Actor has not been started, you need to invoke 'actor.start' before using it") + } else throw new IllegalStateException( + "Actor has not been started, you need to invoke 'actor.start' before using it") } /** @@ -445,7 +507,8 @@ trait Actor extends Logging with TransactionManagement { _linkedActors.remove(actor) actor._supervisor = None log.debug("Unlinking actor [%s] from actor [%s]", actor, this) - } else throw new IllegalStateException("Actor has not been started, you need to invoke 'actor.start' before using it") + } else throw new IllegalStateException( + "Actor has not been started, you need to invoke 'actor.start' before using it") } /** @@ -527,7 +590,7 @@ trait Actor extends Logging with TransactionManagement { // ==== IMPLEMENTATION DETAILS ==== // ================================ - private def postMessageToMailbox(message: AnyRef): Unit = _remoteFlagLock.withReadLock { // the price you pay for being able to make an actor remote at runtime + private def postMessageToMailbox(message: AnyRef, sender: Option[Actor]): Unit = _remoteFlagLock.withReadLock { // the price you pay for being able to make an actor remote at runtime if (_remoteAddress.isDefined) { val requestBuilder = RemoteRequest.newBuilder .setId(RemoteRequestIdFactory.nextId) @@ -541,7 +604,7 @@ trait Actor extends Logging with TransactionManagement { RemoteProtocolBuilder.setMessage(message, requestBuilder) RemoteClient.clientFor(_remoteAddress.get).send(requestBuilder.build) } else { - val handle = new MessageInvocation(this, message, None, currentTransaction.get) + val handle = new MessageInvocation(this, message, None, sender, currentTransaction.get) handle.send } } @@ -560,10 +623,11 @@ trait Actor extends Logging with TransactionManagement { if (id.isDefined) requestBuilder.setSupervisorUuid(id.get) val future = RemoteClient.clientFor(_remoteAddress.get).send(requestBuilder.build) if (future.isDefined) future.get - else throw new IllegalStateException("Expected a future from remote call to actor " + toString) + else throw new IllegalStateException( + "Expected a future from remote call to actor " + toString) } else { val future = new DefaultCompletableFutureResult(timeout) - val handle = new MessageInvocation(this, message, Some(future), currentTransaction.get) + val handle = new MessageInvocation(this, message, Some(future), None, currentTransaction.get) handle.send future } @@ -581,16 +645,17 @@ trait Actor extends Logging with TransactionManagement { setTransaction(messageHandle.tx) val message = messageHandle.message //serializeMessage(messageHandle.message) - val future = messageHandle.future + senderFuture = messageHandle.future + sender = messageHandle.sender + try { - senderFuture = future if (base.isDefinedAt(message)) base(message) // invoke user actor's receive partial function else throw new IllegalArgumentException("No handler matching message [" + message + "] in " + toString) } catch { case e => // FIXME to fix supervisor restart of remote actor for oneway calls, inject a supervisor proxy that can send notification back to client if (_supervisor.isDefined) _supervisor.get ! Exit(this, e) - if (future.isDefined) future.get.completeWithException(this, e) + if (senderFuture.isDefined) senderFuture.get.completeWithException(this, e) else e.printStackTrace } finally { clearTransaction @@ -601,23 +666,25 @@ trait Actor extends Logging with TransactionManagement { setTransaction(messageHandle.tx) val message = messageHandle.message //serializeMessage(messageHandle.message) - val future = messageHandle.future + senderFuture = messageHandle.future + sender = messageHandle.sender def proceed = { try { incrementTransaction if (base.isDefinedAt(message)) base(message) // invoke user actor's receive partial function - else throw new IllegalArgumentException("Actor " + toString + " could not process message [" + message + "] since no matching 'case' clause in its 'receive' method could be found") + else throw new IllegalArgumentException( + "Actor " + toString + " could not process message [" + message + "]" + + "\n\tsince no matching 'case' clause in its 'receive' method could be found") } finally { decrementTransaction } } try { - senderFuture = future if (isTransactionRequiresNew && !isTransactionInScope) { if (senderFuture.isEmpty) throw new StmException( - "\n\tCan't continue transaction in a one-way fire-forget message send" + + "Can't continue transaction in a one-way fire-forget message send" + "\n\tE.g. using Actor '!' method or Active Object 'void' method" + "\n\tPlease use the Actor '!!', '!?' methods or Active Object method with non-void return type") atomic { @@ -627,12 +694,9 @@ trait Actor extends Logging with TransactionManagement { } catch { case e => e.printStackTrace - - if (future.isDefined) future.get.completeWithException(this, e) + if (senderFuture.isDefined) senderFuture.get.completeWithException(this, e) else e.printStackTrace - clearTransaction // need to clear currentTransaction before call to supervisor - // FIXME to fix supervisor restart of remote actor for oneway calls, inject a supervisor proxy that can send notification back to client if (_supervisor.isDefined) _supervisor.get ! Exit(this, e) } finally { @@ -651,8 +715,7 @@ trait Actor extends Logging with TransactionManagement { case HotSwap(code) => _hotswap = code case Restart(reason) => restart(reason) case Exit(dead, reason) => handleTrapExit(dead, reason) - case Kill(killer) => throw new ActorKilledException(this, killer) -// case TransactionalInit => initTransactionalState + case Kill => throw new ActorKilledException(this) } private[this] def handleTrapExit(dead: Actor, reason: Throwable): Unit = { @@ -663,7 +726,9 @@ trait Actor extends Logging with TransactionManagement { case AllForOneStrategy(maxNrOfRetries, withinTimeRange) => restartLinkedActors(reason) case OneForOneStrategy(maxNrOfRetries, withinTimeRange) => dead.restart(reason) } - } else throw new IllegalStateException("No 'faultHandler' defined for actor with the 'trapExit' member field set to non-empty list of exception classes - can't proceed " + toString) + } else throw new IllegalStateException( + "No 'faultHandler' defined for an actor with the 'trapExit' member field defined " + + "\n\tto non-empty list of exception classes - can't proceed " + toString) } else { if (_supervisor.isDefined) _supervisor.get ! Exit(dead, reason) // if 'trapExit' is not defined then pass the Exit on } @@ -672,8 +737,7 @@ trait Actor extends Logging with TransactionManagement { private[this] def restartLinkedActors(reason: AnyRef) = { _linkedActors.toArray.toList.asInstanceOf[List[Actor]].foreach { actor => actor.lifeCycle match { - case None => throw new IllegalStateException("Actor [" + actor.id + "] does not have a life-cycle defined.") - case Some(LifeCycle(scope, _)) => { + case LifeCycle(scope, _) => { scope match { case Permanent => actor.restart(reason) diff --git a/akka-actors/src/main/scala/actor/Scheduler.scala b/akka-actors/src/main/scala/actor/Scheduler.scala index 6266c17942..9b9ee8bc7e 100644 --- a/akka-actors/src/main/scala/actor/Scheduler.scala +++ b/akka-actors/src/main/scala/actor/Scheduler.scala @@ -28,7 +28,7 @@ case class SchedulerException(msg: String, e: Throwable) extends RuntimeExceptio * which is licensed under the Apache 2 License. */ class ScheduleActor(val receiver: Actor, val future: ScheduledFuture[AnyRef]) extends Actor with Logging { - lifeCycle = Some(LifeCycle(Permanent)) + lifeCycle = LifeCycle(Permanent) def receive = { case UnSchedule => diff --git a/akka-actors/src/main/scala/actor/Supervisor.scala b/akka-actors/src/main/scala/actor/Supervisor.scala index 1dadd2cdac..ec65fbfec7 100644 --- a/akka-actors/src/main/scala/actor/Supervisor.scala +++ b/akka-actors/src/main/scala/actor/Supervisor.scala @@ -8,20 +8,10 @@ import se.scalablesolutions.akka.config.ScalaConfig._ import se.scalablesolutions.akka.config.{ConfiguratorRepository, Configurator} import se.scalablesolutions.akka.util.Helpers._ import se.scalablesolutions.akka.util.Logging +import se.scalablesolutions.akka.dispatch.Dispatchers import java.util.concurrent.ConcurrentHashMap -/** - * Messages that the supervisor responds to and returns. - * - * @author Jonas Bonér - */ -sealed abstract class SupervisorMessage -case object StartSupervisor extends SupervisorMessage -case object StopSupervisor extends SupervisorMessage -case class ConfigureSupervisor(config: SupervisorConfig, factory: SupervisorFactory) extends SupervisorMessage -case object ConfigSupervisorSuccess extends SupervisorMessage - sealed abstract class FaultHandlingStrategy case class AllForOneStrategy(maxNrOfRetries: Int, withinTimeRange: Int) extends FaultHandlingStrategy case class OneForOneStrategy(maxNrOfRetries: Int, withinTimeRange: Int) extends FaultHandlingStrategy @@ -93,7 +83,7 @@ sealed class Supervisor private[akka] (handler: FaultHandlingStrategy) extends Actor with Logging with Configurator { trapExit = List(classOf[Throwable]) faultHandler = Some(handler) - //dispatcher = Dispatchers.newThreadBasedDispatcher(this) + dispatcher = Dispatchers.newThreadBasedDispatcher(this) val actors = new ConcurrentHashMap[String, Actor] @@ -103,9 +93,8 @@ sealed class Supervisor private[akka] (handler: FaultHandlingStrategy) def isDefined(clazz: Class[_]): Boolean = actors.containsKey(clazz.getName) - override def start = { + override def start = synchronized { ConfiguratorRepository.registerConfigurator(this) - actors.values.toArray.toList.foreach(println) _linkedActors.toArray.toList.asInstanceOf[List[Actor]].foreach { actor => actor.start log.info("Starting actor: %s", actor) @@ -113,7 +102,7 @@ sealed class Supervisor private[akka] (handler: FaultHandlingStrategy) super[Actor].start } - override def stop = { + override def stop = synchronized { super[Actor].stop _linkedActors.toArray.toList.asInstanceOf[List[Actor]].foreach { actor => actor.stop @@ -123,21 +112,20 @@ sealed class Supervisor private[akka] (handler: FaultHandlingStrategy) } def receive = { - case _ => throw new IllegalArgumentException("Supervisor does not respond to any messages") + case unknown => throw new IllegalArgumentException("Supervisor does not respond to any messages. Unknown message [" + unknown + "]") } def configure(config: SupervisorConfig, factory: SupervisorFactory) = config match { case SupervisorConfig(_, servers) => servers.map(server => server match { - case Supervise(actor, lifecycle) => + case Supervise(actor, lifeCycle) => actors.put(actor.getClass.getName, actor) - actor.lifeCycle = Some(lifecycle) + actor.lifeCycle = lifeCycle startLink(actor) case SupervisorConfig(_, _) => // recursive configuration - val supervisor = factory.newInstanceFor(server.asInstanceOf[SupervisorConfig]) - supervisor ! StartSupervisor + factory.newInstanceFor(server.asInstanceOf[SupervisorConfig]).start // FIXME what to do with recursively supervisors? }) } diff --git a/akka-actors/src/main/scala/dispatch/Dispatchers.scala b/akka-actors/src/main/scala/dispatch/Dispatchers.scala index ed4bd6d704..a82191af1a 100644 --- a/akka-actors/src/main/scala/dispatch/Dispatchers.scala +++ b/akka-actors/src/main/scala/dispatch/Dispatchers.scala @@ -39,7 +39,9 @@ import se.scalablesolutions.akka.actor.Actor * @author Jonas Bonér */ object Dispatchers { - + + object globalEventBasedThreadPoolDispatcher extends EventBasedThreadPoolDispatcher("global:eventbased:dispatcher") + /** * Creates an event based dispatcher serving multiple (millions) of actors through a thread pool. * Has a fluent builder interface for configuring its semantics. diff --git a/akka-actors/src/main/scala/dispatch/Reactor.scala b/akka-actors/src/main/scala/dispatch/Reactor.scala index 36be55a391..38c311097d 100644 --- a/akka-actors/src/main/scala/dispatch/Reactor.scala +++ b/akka-actors/src/main/scala/dispatch/Reactor.scala @@ -39,6 +39,7 @@ trait MessageDemultiplexer { class MessageInvocation(val receiver: Actor, val message: AnyRef, val future: Option[CompletableFutureResult], + val sender: Option[Actor], val tx: Option[Transaction]) { if (receiver == null) throw new IllegalArgumentException("receiver is null") if (message == null) throw new IllegalArgumentException("message is null") @@ -65,6 +66,10 @@ class MessageInvocation(val receiver: Actor, } override def toString(): String = synchronized { - "MessageInvocation[message = " + message + ", receiver = " + receiver + ", future = " + future + ", tx = " + tx + "]" + "MessageInvocation[message = " + message + + ", receiver = " + receiver + + ", sender = " + sender + + ", future = " + future + + ", tx = " + tx + "]" } } diff --git a/akka-actors/src/main/scala/nio/RemoteClient.scala b/akka-actors/src/main/scala/nio/RemoteClient.scala index c25782fe31..4e1a777181 100644 --- a/akka-actors/src/main/scala/nio/RemoteClient.scala +++ b/akka-actors/src/main/scala/nio/RemoteClient.scala @@ -155,6 +155,7 @@ class RemoteClientHandler(val name: String, } override def messageReceived(ctx: ChannelHandlerContext, event: MessageEvent) { + import Actor._ try { val result = event.getMessage if (result.isInstanceOf[RemoteReply]) { diff --git a/akka-actors/src/main/scala/nio/RemoteServer.scala b/akka-actors/src/main/scala/nio/RemoteServer.scala index 0c89ac6246..635b231e52 100755 --- a/akka-actors/src/main/scala/nio/RemoteServer.scala +++ b/akka-actors/src/main/scala/nio/RemoteServer.scala @@ -113,6 +113,7 @@ class RemoteServerHandler(val name: String, val applicationLoader: Option[ClassL } private def dispatchToActor(request: RemoteRequest, channel: Channel) = { + import Actor._ log.debug("Dispatching to remote actor [%s]", request.getTarget) val actor = createActor(request.getTarget, request.getTimeout) actor.start diff --git a/akka-actors/src/main/scala/stm/DataFlowVariable.scala b/akka-actors/src/main/scala/stm/DataFlowVariable.scala index ec47f0983f..44a40f50af 100644 --- a/akka-actors/src/main/scala/stm/DataFlowVariable.scala +++ b/akka-actors/src/main/scala/stm/DataFlowVariable.scala @@ -24,11 +24,11 @@ object DataFlow { thread } - def thread[MessageType, ReturnType](body: MessageType => ReturnType) = + def thread[MessageType, ReturnType](body: MessageType => ReturnType) = new ReactiveEventBasedThread(body).start private class IsolatedEventBasedThread(body: => Unit) extends Actor { - def act = loop { + def act = loop { react { case 'start => body case 'exit => exit() @@ -37,7 +37,7 @@ object DataFlow { } private class ReactiveEventBasedThread[MessageType, ReturnType](body: MessageType => ReturnType) extends Actor { - def act = loop { + def act = loop { react { case 'exit => exit() case message => sender ! body(message.asInstanceOf[MessageType]) @@ -48,7 +48,7 @@ object DataFlow { /** * @author Jonas Bonér */ - sealed class DataFlowVariable[T] { + sealed class DataFlowVariable[T] { private sealed abstract class DataFlowVariableMessage private case class Set[T](value: T) extends DataFlowVariableMessage @@ -73,7 +73,7 @@ object DataFlow { private class Out[T](dataFlow: DataFlowVariable[T]) extends Actor { var reader: Option[OutputChannel[Any]] = None def act = loop { react { - case Get => + case Get => val ref = dataFlow.value.get if (ref.isDefined) reply(ref.get) else reader = Some(sender) case Set(v) => if (reader.isDefined) reader.get ! v @@ -380,5 +380,3 @@ object Test5 extends Application { //System.gc } - - diff --git a/akka-actors/src/test/scala/ActorFireForgetRequestReplyTest.scala b/akka-actors/src/test/scala/ActorFireForgetRequestReplyTest.scala new file mode 100644 index 0000000000..826f157593 --- /dev/null +++ b/akka-actors/src/test/scala/ActorFireForgetRequestReplyTest.scala @@ -0,0 +1,51 @@ +package se.scalablesolutions.akka.actor + +import org.scalatest.junit.JUnitSuite +import org.junit.Test + +object state { + var s = "NIL" +} + +class ReplyActor extends Actor { + def receive = { + case "Send" => reply("Reply") + case "SendImplicit" => sender.get ! "ReplyImplicit" + } +} + +class SenderActor(replyActor: Actor) extends Actor { + def receive = { + case "Init" => replyActor ! "Send" + case "Reply" => state.s = "Reply" + case "InitImplicit" => replyActor ! "SendImplicit" + case "ReplyImplicit" => state.s = "ReplyImplicit" + } +} + +class ActorFireForgetRequestReplyTest extends JUnitSuite { + + @Test + def shouldReplyToBangMessageUsingReply = { + import Actor._ + val replyActor = new ReplyActor + replyActor.start + val senderActor = new SenderActor(replyActor) + senderActor.start + senderActor ! "Init" + Thread.sleep(10000) + assert("Reply" === state.s) + } + + @Test + def shouldReplyToBangMessageUsingImplicitSender = { + import Actor._ + val replyActor = new ReplyActor + replyActor.start + val senderActor = new SenderActor(replyActor) + senderActor.start + senderActor ! "InitImplicit" + Thread.sleep(10000) + assert("ReplyImplicit" === state.s) + } +} diff --git a/akka-actors/src/test/scala/EventBasedSingleThreadActorTest.scala b/akka-actors/src/test/scala/EventBasedSingleThreadActorTest.scala index 67fbf89da8..bd7389e676 100644 --- a/akka-actors/src/test/scala/EventBasedSingleThreadActorTest.scala +++ b/akka-actors/src/test/scala/EventBasedSingleThreadActorTest.scala @@ -8,6 +8,7 @@ import org.junit.Test import se.scalablesolutions.akka.dispatch.Dispatchers class EventBasedSingleThreadActorTest extends JUnitSuite { + import Actor._ private val unit = TimeUnit.MILLISECONDS class TestActor extends Actor { diff --git a/akka-actors/src/test/scala/EventBasedSingleThreadDispatcherTest.scala b/akka-actors/src/test/scala/EventBasedSingleThreadDispatcherTest.scala index 2997c3b4f5..649d95f4d2 100644 --- a/akka-actors/src/test/scala/EventBasedSingleThreadDispatcherTest.scala +++ b/akka-actors/src/test/scala/EventBasedSingleThreadDispatcherTest.scala @@ -61,7 +61,7 @@ class EventBasedSingleThreadDispatcherTest extends JUnitSuite { dispatcher.registerHandler(key1, new TestMessageHandle(handleLatch)) dispatcher.start for (i <- 0 until 100) { - dispatcher.messageQueue.append(new MessageInvocation(key1, new Object, None, None)) + dispatcher.messageQueue.append(new MessageInvocation(key1, new Object, None, None, None)) } assert(handleLatch.await(5, TimeUnit.SECONDS)) assert(!threadingIssueDetected.get) @@ -73,8 +73,8 @@ class EventBasedSingleThreadDispatcherTest extends JUnitSuite { dispatcher.registerHandler(key1, new TestMessageHandle(handleLatch)) dispatcher.registerHandler(key2, new TestMessageHandle(handleLatch)) dispatcher.start - dispatcher.messageQueue.append(new MessageInvocation(key1, new Object, None, None)) - dispatcher.messageQueue.append(new MessageInvocation(key2, new Object, None, None)) + dispatcher.messageQueue.append(new MessageInvocation(key1, new Object, None, None, None)) + dispatcher.messageQueue.append(new MessageInvocation(key2, new Object, None, None, None)) assert(handleLatch.await(5, TimeUnit.SECONDS)) assert(!threadingIssueDetected.get) } @@ -106,8 +106,8 @@ class EventBasedSingleThreadDispatcherTest extends JUnitSuite { }) dispatcher.start for (i <- 0 until 100) { - dispatcher.messageQueue.append(new MessageInvocation(key1, new java.lang.Integer(i), None, None)) - dispatcher.messageQueue.append(new MessageInvocation(key2, new java.lang.Integer(i), None, None)) + dispatcher.messageQueue.append(new MessageInvocation(key1, new java.lang.Integer(i), None, None, None)) + dispatcher.messageQueue.append(new MessageInvocation(key2, new java.lang.Integer(i), None, None, None)) } assert(handleLatch.await(5, TimeUnit.SECONDS)) assert(!threadingIssueDetected.get) diff --git a/akka-actors/src/test/scala/EventBasedThreadPoolActorTest.scala b/akka-actors/src/test/scala/EventBasedThreadPoolActorTest.scala index e82784cc67..55345ec25e 100644 --- a/akka-actors/src/test/scala/EventBasedThreadPoolActorTest.scala +++ b/akka-actors/src/test/scala/EventBasedThreadPoolActorTest.scala @@ -6,6 +6,7 @@ import org.scalatest.junit.JUnitSuite import org.junit.Test class EventBasedThreadPoolActorTest extends JUnitSuite { + import Actor._ private val unit = TimeUnit.MILLISECONDS class TestActor extends Actor { diff --git a/akka-actors/src/test/scala/EventBasedThreadPoolDispatcherTest.scala b/akka-actors/src/test/scala/EventBasedThreadPoolDispatcherTest.scala index 84d778a39d..f8c0107d05 100644 --- a/akka-actors/src/test/scala/EventBasedThreadPoolDispatcherTest.scala +++ b/akka-actors/src/test/scala/EventBasedThreadPoolDispatcherTest.scala @@ -67,7 +67,7 @@ class EventBasedThreadPoolDispatcherTest extends JUnitSuite { }) dispatcher.start for (i <- 0 until 10) { - dispatcher.messageQueue.append(new MessageInvocation(key1, new Object, None, None)) + dispatcher.messageQueue.append(new MessageInvocation(key1, new Object, None, None, None)) } assert(handleLatch.await(5, TimeUnit.SECONDS)) assert(!threadingIssueDetected.get) @@ -109,10 +109,10 @@ class EventBasedThreadPoolDispatcherTest extends JUnitSuite { } }) dispatcher.start - dispatcher.messageQueue.append(new MessageInvocation(key1, "Sending Message 1", None, None)) - dispatcher.messageQueue.append(new MessageInvocation(key1, "Sending Message 1.1", None, None)) - dispatcher.messageQueue.append(new MessageInvocation(key2, "Sending Message 2", None, None)) - dispatcher.messageQueue.append(new MessageInvocation(key2, "Sending Message 2.2", None, None)) + dispatcher.messageQueue.append(new MessageInvocation(key1, "Sending Message 1", None, None, None)) + dispatcher.messageQueue.append(new MessageInvocation(key1, "Sending Message 1.1", None, None, None)) + dispatcher.messageQueue.append(new MessageInvocation(key2, "Sending Message 2", None, None, None)) + dispatcher.messageQueue.append(new MessageInvocation(key2, "Sending Message 2.2", None, None, None)) handlersBarrier.await(5, TimeUnit.SECONDS) assert(!threadingIssueDetected.get) @@ -151,8 +151,8 @@ class EventBasedThreadPoolDispatcherTest extends JUnitSuite { }) dispatcher.start for (i <- 0 until 100) { - dispatcher.messageQueue.append(new MessageInvocation(key1, new java.lang.Integer(i), None, None)) - dispatcher.messageQueue.append(new MessageInvocation(key2, new java.lang.Integer(i), None, None)) + dispatcher.messageQueue.append(new MessageInvocation(key1, new java.lang.Integer(i), None, None, None)) + dispatcher.messageQueue.append(new MessageInvocation(key2, new java.lang.Integer(i), None, None, None)) } assert(handleLatch.await(5, TimeUnit.SECONDS)) assert(!threadingIssueDetected.get) diff --git a/akka-actors/src/test/scala/RemoteActorTest.scala b/akka-actors/src/test/scala/RemoteActorTest.scala index 1b6cb5bd76..bea33a50d9 100644 --- a/akka-actors/src/test/scala/RemoteActorTest.scala +++ b/akka-actors/src/test/scala/RemoteActorTest.scala @@ -27,6 +27,7 @@ class RemoteActorSpecActorBidirectional extends Actor { } class RemoteActorTest extends JUnitSuite { + import Actor._ akka.Config.config new Thread(new Runnable() { def run = { diff --git a/akka-actors/src/test/scala/RemoteSupervisorTest.scala b/akka-actors/src/test/scala/RemoteSupervisorTest.scala index 2150707fac..9405af6dc9 100644 --- a/akka-actors/src/test/scala/RemoteSupervisorTest.scala +++ b/akka-actors/src/test/scala/RemoteSupervisorTest.scala @@ -20,6 +20,7 @@ object Log { * @author Jonas Bonér */ class RemoteSupervisorTest extends JUnitSuite { + import Actor._ akka.Config.config new Thread(new Runnable() { def run = { @@ -35,7 +36,7 @@ class RemoteSupervisorTest extends JUnitSuite { @Test def shouldStartServer = { Log.messageLog = "" val sup = getSingleActorAllForOneSupervisor - sup ! StartSupervisor + sup.start expect("pong") { (pingpong1 !! BinaryString("Ping")).getOrElse("nil") @@ -45,7 +46,7 @@ class RemoteSupervisorTest extends JUnitSuite { @Test def shouldKillSingleActorOneForOne = { Log.messageLog = "" val sup = getSingleActorOneForOneSupervisor - sup ! StartSupervisor + sup.start Thread.sleep(500) intercept[RuntimeException] { pingpong1 !! BinaryString("Die") @@ -59,7 +60,7 @@ class RemoteSupervisorTest extends JUnitSuite { @Test def shouldCallKillCallSingleActorOneForOne = { Log.messageLog = "" val sup = getSingleActorOneForOneSupervisor - sup ! StartSupervisor + sup.start Thread.sleep(500) expect("pong") { (pingpong1 !! BinaryString("Ping")).getOrElse("nil") @@ -87,7 +88,7 @@ class RemoteSupervisorTest extends JUnitSuite { @Test def shouldKillSingleActorAllForOne = { Log.messageLog = "" val sup = getSingleActorAllForOneSupervisor - sup ! StartSupervisor + sup.start Thread.sleep(500) intercept[RuntimeException] { pingpong1 !! BinaryString("Die") @@ -101,7 +102,7 @@ class RemoteSupervisorTest extends JUnitSuite { @Test def shouldCallKillCallSingleActorAllForOne = { Log.messageLog = "" val sup = getSingleActorAllForOneSupervisor - sup ! StartSupervisor + sup.start Thread.sleep(500) expect("pong") { (pingpong1 !! BinaryString("Ping")).getOrElse("nil") @@ -129,7 +130,7 @@ class RemoteSupervisorTest extends JUnitSuite { @Test def shouldKillMultipleActorsOneForOne = { Log.messageLog = "" val sup = getMultipleActorsOneForOneConf - sup ! StartSupervisor + sup.start Thread.sleep(500) intercept[RuntimeException] { pingpong3 !! BinaryString("Die") @@ -143,7 +144,7 @@ class RemoteSupervisorTest extends JUnitSuite { def tesCallKillCallMultipleActorsOneForOne = { Log.messageLog = "" val sup = getMultipleActorsOneForOneConf - sup ! StartSupervisor + sup.start Thread.sleep(500) expect("pong") { (pingpong1 !! BinaryString("Ping")).getOrElse("nil") @@ -187,7 +188,7 @@ class RemoteSupervisorTest extends JUnitSuite { @Test def shouldKillMultipleActorsAllForOne = { Log.messageLog = "" val sup = getMultipleActorsAllForOneConf - sup ! StartSupervisor + sup.start Thread.sleep(500) intercept[RuntimeException] { pingpong2 !! BinaryString("Die") @@ -201,7 +202,7 @@ class RemoteSupervisorTest extends JUnitSuite { def tesCallKillCallMultipleActorsAllForOne = { Log.messageLog = "" val sup = getMultipleActorsAllForOneConf - sup ! StartSupervisor + sup.start Thread.sleep(500) expect("pong") { (pingpong1 !! BinaryString("Ping")).getOrElse("nil") @@ -246,7 +247,7 @@ class RemoteSupervisorTest extends JUnitSuite { @Test def shouldOneWayKillSingleActorOneForOne = { Logg.messageLog = "" val sup = getSingleActorOneForOneSupervisor - sup ! StartSupervisor + sup.start Thread.sleep(500) pingpong1 ! BinaryString("Die") Thread.sleep(500) @@ -258,7 +259,7 @@ class RemoteSupervisorTest extends JUnitSuite { @Test def shouldOneWayCallKillCallSingleActorOneForOne = { Logg.messageLog = "" val sup = getSingleActorOneForOneSupervisor - sup ! StartSupervisor + sup.start Thread.sleep(500) pingpong1 ! OneWay Thread.sleep(500) @@ -282,7 +283,7 @@ class RemoteSupervisorTest extends JUnitSuite { @Test def shouldOneWayKillSingleActorAllForOne = { Logg.messageLog = "" val sup = getSingleActorAllForOneSupervisor - sup ! StartSupervisor + sup.start Thread.sleep(500) intercept[RuntimeException] { pingpong1 ! BinaryString("Die") @@ -296,7 +297,7 @@ class RemoteSupervisorTest extends JUnitSuite { @Test def shouldOneWayCallKillCallSingleActorAllForOne = { Logg.messageLog = "" val sup = getSingleActorAllForOneSupervisor - sup ! StartSupervisor + sup.start Thread.sleep(500) expect("pong") { (pingpong1 ! BinaryString("Ping")).getOrElse("nil") @@ -324,7 +325,7 @@ class RemoteSupervisorTest extends JUnitSuite { @Test def shouldOneWayKillMultipleActorsOneForOne = { Logg.messageLog = "" val sup = getMultipleActorsOneForOneConf - sup ! StartSupervisor + sup.start Thread.sleep(500) intercept[RuntimeException] { pingpong3 ! BinaryString("Die") @@ -338,7 +339,7 @@ class RemoteSupervisorTest extends JUnitSuite { def tesOneWayCallKillCallMultipleActorsOneForOne = { Logg.messageLog = "" val sup = getMultipleActorsOneForOneConf - sup ! StartSupervisor + sup.start Thread.sleep(500) expect("pong") { (pingpong1 ! BinaryString("Ping")).getOrElse("nil") @@ -382,7 +383,7 @@ class RemoteSupervisorTest extends JUnitSuite { @Test def shouldOneWayKillMultipleActorsAllForOne = { Logg.messageLog = "" val sup = getMultipleActorsAllForOneConf - sup ! StartSupervisor + sup.start Thread.sleep(500) intercept[RuntimeException] { pingpong2 ! BinaryString("Die") @@ -396,7 +397,7 @@ class RemoteSupervisorTest extends JUnitSuite { def tesOneWayCallKillCallMultipleActorsAllForOne = { Logg.messageLog = "" val sup = getMultipleActorsAllForOneConf - sup ! StartSupervisor + sup.start Thread.sleep(500) expect("pong") { pingpong1 ! BinaryString("Ping") @@ -442,7 +443,7 @@ class RemoteSupervisorTest extends JUnitSuite { @Test def shouldNestedSupervisorsTerminateFirstLevelActorAllForOne = { Logg.messageLog = "" val sup = getNestedSupervisorsAllForOneConf - sup ! StartSupervisor + sup.start intercept[RuntimeException] { pingpong1 !! BinaryString("Die") } diff --git a/akka-actors/src/test/scala/SupervisorTest.scala b/akka-actors/src/test/scala/SupervisorTest.scala index f2a98727d6..df59ee832c 100644 --- a/akka-actors/src/test/scala/SupervisorTest.scala +++ b/akka-actors/src/test/scala/SupervisorTest.scala @@ -13,6 +13,7 @@ import org.junit.Test * @author Jonas Bonér */ class SupervisorTest extends JUnitSuite { + import Actor._ var messageLog: String = "" var oneWayLog: String = "" @@ -24,7 +25,7 @@ class SupervisorTest extends JUnitSuite { @Test def shouldStartServer = { messageLog = "" val sup = getSingleActorAllForOneSupervisor - sup ! StartSupervisor + sup.start expect("pong") { (pingpong1 !! Ping).getOrElse("nil") @@ -34,7 +35,7 @@ class SupervisorTest extends JUnitSuite { @Test def shouldKillSingleActorOneForOne = { messageLog = "" val sup = getSingleActorOneForOneSupervisor - sup ! StartSupervisor + sup.start Thread.sleep(500) intercept[RuntimeException] { pingpong1 !! Die @@ -48,7 +49,7 @@ class SupervisorTest extends JUnitSuite { @Test def shouldCallKillCallSingleActorOneForOne = { messageLog = "" val sup = getSingleActorOneForOneSupervisor - sup ! StartSupervisor + sup.start Thread.sleep(500) expect("pong") { (pingpong1 !! Ping).getOrElse("nil") @@ -76,7 +77,7 @@ class SupervisorTest extends JUnitSuite { @Test def shouldKillSingleActorAllForOne = { messageLog = "" val sup = getSingleActorAllForOneSupervisor - sup ! StartSupervisor + sup.start Thread.sleep(500) intercept[RuntimeException] { pingpong1 !! Die @@ -90,7 +91,7 @@ class SupervisorTest extends JUnitSuite { @Test def shouldCallKillCallSingleActorAllForOne = { messageLog = "" val sup = getSingleActorAllForOneSupervisor - sup ! StartSupervisor + sup.start Thread.sleep(500) expect("pong") { (pingpong1 !! Ping).getOrElse("nil") @@ -118,7 +119,7 @@ class SupervisorTest extends JUnitSuite { @Test def shouldKillMultipleActorsOneForOne = { messageLog = "" val sup = getMultipleActorsOneForOneConf - sup ! StartSupervisor + sup.start Thread.sleep(500) intercept[RuntimeException] { pingpong3 !! Die @@ -132,7 +133,7 @@ class SupervisorTest extends JUnitSuite { def tesCallKillCallMultipleActorsOneForOne = { messageLog = "" val sup = getMultipleActorsOneForOneConf - sup ! StartSupervisor + sup.start Thread.sleep(500) expect("pong") { (pingpong1 !! Ping).getOrElse("nil") @@ -176,7 +177,7 @@ class SupervisorTest extends JUnitSuite { @Test def shouldKillMultipleActorsAllForOne = { messageLog = "" val sup = getMultipleActorsAllForOneConf - sup ! StartSupervisor + sup.start Thread.sleep(500) intercept[RuntimeException] { pingpong2 !! Die @@ -190,7 +191,7 @@ class SupervisorTest extends JUnitSuite { def tesCallKillCallMultipleActorsAllForOne = { messageLog = "" val sup = getMultipleActorsAllForOneConf - sup ! StartSupervisor + sup.start Thread.sleep(500) expect("pong") { (pingpong1 !! Ping).getOrElse("nil") @@ -234,7 +235,7 @@ class SupervisorTest extends JUnitSuite { @Test def shouldOneWayKillSingleActorOneForOne = { messageLog = "" val sup = getSingleActorOneForOneSupervisor - sup ! StartSupervisor + sup.start Thread.sleep(500) pingpong1 ! Die Thread.sleep(500) @@ -246,7 +247,7 @@ class SupervisorTest extends JUnitSuite { @Test def shouldOneWayCallKillCallSingleActorOneForOne = { messageLog = "" val sup = getSingleActorOneForOneSupervisor - sup ! StartSupervisor + sup.start Thread.sleep(500) pingpong1 ! OneWay Thread.sleep(500) @@ -269,7 +270,7 @@ class SupervisorTest extends JUnitSuite { @Test def shouldOneWayKillSingleActorAllForOne = { messageLog = "" val sup = getSingleActorAllForOneSupervisor - sup ! StartSupervisor + sup.start Thread.sleep(500) intercept[RuntimeException] { pingpong1 ! Die @@ -283,7 +284,7 @@ class SupervisorTest extends JUnitSuite { @Test def shouldOneWayCallKillCallSingleActorAllForOne = { messageLog = "" val sup = getSingleActorAllForOneSupervisor - sup ! StartSupervisor + sup.start Thread.sleep(500) expect("pong") { (pingpong1 ! Ping).getOrElse("nil") @@ -311,7 +312,7 @@ class SupervisorTest extends JUnitSuite { @Test def shouldOneWayKillMultipleActorsOneForOne = { messageLog = "" val sup = getMultipleActorsOneForOneConf - sup ! StartSupervisor + sup.start Thread.sleep(500) intercept[RuntimeException] { pingpong3 ! Die @@ -325,7 +326,7 @@ class SupervisorTest extends JUnitSuite { def tesOneWayCallKillCallMultipleActorsOneForOne = { messageLog = "" val sup = getMultipleActorsOneForOneConf - sup ! StartSupervisor + sup.start Thread.sleep(500) expect("pong") { (pingpong1 ! Ping).getOrElse("nil") @@ -369,7 +370,7 @@ class SupervisorTest extends JUnitSuite { @Test def shouldOneWayKillMultipleActorsAllForOne = { messageLog = "" val sup = getMultipleActorsAllForOneConf - sup ! StartSupervisor + sup.start Thread.sleep(500) intercept[RuntimeException] { pingpong2 ! Die @@ -383,7 +384,7 @@ class SupervisorTest extends JUnitSuite { def tesOneWayCallKillCallMultipleActorsAllForOne = { messageLog = "" val sup = getMultipleActorsAllForOneConf - sup ! StartSupervisor + sup.start Thread.sleep(500) expect("pong") { pingpong1 ! Ping @@ -429,7 +430,7 @@ class SupervisorTest extends JUnitSuite { @Test def shouldNestedSupervisorsTerminateFirstLevelActorAllForOne = { messageLog = "" val sup = getNestedSupervisorsAllForOneConf - sup ! StartSupervisor + sup.start intercept[RuntimeException] { pingpong1 !! Die } diff --git a/akka-actors/src/test/scala/ThreadBasedActorTest.scala b/akka-actors/src/test/scala/ThreadBasedActorTest.scala index e39b9322f1..dca6634acc 100644 --- a/akka-actors/src/test/scala/ThreadBasedActorTest.scala +++ b/akka-actors/src/test/scala/ThreadBasedActorTest.scala @@ -8,6 +8,7 @@ import org.junit.Test import se.scalablesolutions.akka.dispatch.Dispatchers class ThreadBasedActorTest extends JUnitSuite { + import Actor._ private val unit = TimeUnit.MILLISECONDS class TestActor extends Actor { diff --git a/akka-actors/src/test/scala/ThreadBasedDispatcherTest.scala b/akka-actors/src/test/scala/ThreadBasedDispatcherTest.scala index 1495257a7f..b434762b37 100644 --- a/akka-actors/src/test/scala/ThreadBasedDispatcherTest.scala +++ b/akka-actors/src/test/scala/ThreadBasedDispatcherTest.scala @@ -57,7 +57,7 @@ class ThreadBasedDispatcherTest extends JUnitSuite { val dispatcher = new ThreadBasedDispatcher("name", new TestMessageHandle(handleLatch)) dispatcher.start for (i <- 0 until 100) { - dispatcher.messageQueue.append(new MessageInvocation(key1, new Object, None, None)) + dispatcher.messageQueue.append(new MessageInvocation(key1, new Object, None, None, None)) } assert(handleLatch.await(5, TimeUnit.SECONDS)) assert(!threadingIssueDetected.get) @@ -78,7 +78,7 @@ class ThreadBasedDispatcherTest extends JUnitSuite { }) dispatcher.start for (i <- 0 until 100) { - dispatcher.messageQueue.append(new MessageInvocation(key1, new Integer(i), None, None)) + dispatcher.messageQueue.append(new MessageInvocation(key1, new Integer(i), None, None, None)) } assert(handleLatch.await(5, TimeUnit.SECONDS)) assert(!threadingIssueDetected.get) diff --git a/akka-amqp/src/main/scala/AMQP.scala b/akka-amqp/src/main/scala/AMQP.scala index 3143f41ee6..9f591f9891 100644 --- a/akka-amqp/src/main/scala/AMQP.scala +++ b/akka-amqp/src/main/scala/AMQP.scala @@ -285,7 +285,7 @@ object AMQP extends Actor { val passive: Boolean, val durable: Boolean, val configurationArguments: Map[java.lang.String, Object]) - extends FaultTolerantConnectionActor { self: Consumer => + extends FaultTolerantConnectionActor { consumer: Consumer => faultHandler = Some(OneForOneStrategy(5, 5000)) trapExit = List(classOf[Throwable]) @@ -370,7 +370,7 @@ object AMQP extends Actor { } catch { case cause => log.error("Delivery of message to MessageConsumerListener [%s] failed due to [%s]", listener.toString(exchangeName), cause.toString) - self ! Failure(cause) // pass on and re-throw exception in consumer actor to trigger restart and reconnect + consumer ! Failure(cause) // pass on and re-throw exception in consumer actor to trigger restart and reconnect } } @@ -384,7 +384,7 @@ object AMQP extends Actor { case Some(listener) => log.warning("MessageConsumerListener [%s] is being shutdown by [%s] due to [%s]", listener.toString(exchangeName), signal.getReference, signal.getReason) - self ! UnregisterMessageConsumerListener(listener) + consumer ! UnregisterMessageConsumerListener(listener) } } }) @@ -422,8 +422,6 @@ object AMQP extends Actor { } trait FaultTolerantConnectionActor extends Actor { - lifeCycle = Some(LifeCycle(Permanent)) - val reconnectionTimer = new Timer var connection: Connection = _ diff --git a/akka-util/src/main/scala/Config.scala b/akka-util/src/main/scala/Config.scala index 0359a3a58a..e3e82c7af9 100644 --- a/akka-util/src/main/scala/Config.scala +++ b/akka-util/src/main/scala/Config.scala @@ -35,7 +35,9 @@ object Config extends Logging { Configgy.configure(configFile) log.info("AKKA_HOME is defined to [%s], config loaded from [%s].", HOME.get, configFile) } catch { - case e: ParseException => throw new IllegalStateException("'akka.conf' config file can not be found in [" + HOME + "/config/akka.conf] - aborting. Either add it in the 'config' directory or add it to the classpath.") + case e: ParseException => throw new IllegalStateException( + "'akka.conf' config file can not be found in [" + HOME + "/config/akka.conf] aborting." + + "\n\tEither add it in the 'config' directory or add it to the classpath.") } } else if (System.getProperty("akka.config", "") != "") { val configFile = System.getProperty("akka.config", "") @@ -43,21 +45,26 @@ object Config extends Logging { Configgy.configure(configFile) log.info("Config loaded from -Dakka.config=%s", configFile) } catch { - case e: ParseException => throw new IllegalStateException("Config could not be loaded from -Dakka.config=" + configFile) + case e: ParseException => throw new IllegalStateException( + "Config could not be loaded from -Dakka.config=" + configFile) } } else { try { Configgy.configureFromResource("akka.conf", getClass.getClassLoader) log.info("Config loaded from the application classpath.") } catch { - case e: ParseException => throw new IllegalStateException("'$AKKA_HOME/config/akka.conf' could not be found and no 'akka.conf' can be found on the classpath - aborting. . Either add it in the '$AKKA_HOME/config' directory or add it to the classpath.") + case e: ParseException => throw new IllegalStateException( + "'$AKKA_HOME/config/akka.conf' could not be found" + + "\n\tand no 'akka.conf' can be found on the classpath - aborting." + + "\n\tEither add it in the '$AKKA_HOME/config' directory or add it to the classpath.") } } Configgy.config } val CONFIG_VERSION = config.getString("akka.version", "0") - if (VERSION != CONFIG_VERSION) throw new IllegalStateException("Akka JAR version [" + VERSION + "] is different than the provided config ('akka.conf') version [" + CONFIG_VERSION + "]") + if (VERSION != CONFIG_VERSION) throw new IllegalStateException( + "Akka JAR version [" + VERSION + "] is different than the provided config ('akka.conf') version [" + CONFIG_VERSION + "]") val startTime = System.currentTimeMillis def uptime = (System.currentTimeMillis - startTime) / 1000 diff --git a/changes.xml b/changes.xml index 105309c949..203bd588ac 100644 --- a/changes.xml +++ b/changes.xml @@ -10,6 +10,11 @@ description see http://maven.apache.org/plugins/maven-changes-plugin/usage.html for full guide --> + + + Akka Release Notes @@ -33,11 +38,13 @@ see http://maven.apache.org/plugins/maven-changes-plugin/usage.html for full gui Monadic API to TransactionalRef (use it in for-comprehension) Lightweight actor syntax 'actor { case _ => .. }' New Scala JSON parser based on sjson + Upgraded to Netty 3.2 and Protobuf 2.2 Monadic API to TransactionalRef (use it in for-comprehension) Smoother web app integration; just add akka.conf to WEB-INF/classes, no need for AKKA_HOME Modularization of distribution into a thin core (actors, remoting and STM) and the rest in submodules JSON serialization for Java objects (using Jackson) JSON serialization for Scala objects (using SJSON) + Added implementation for remote actor reconnect upon failure Protobuf serialization for Java and Scala objects SBinary serialization for Scala objects Protobuf as remote protocol From 8109b00e4280ab7349b4c20486670521d139952a Mon Sep 17 00:00:00 2001 From: jboner Date: Sat, 21 Nov 2009 20:51:03 +0100 Subject: [PATCH 05/20] Fixed issue #46: Remote Actor should be defined by target class and UUID --- .../src/main/scala/actor/ActiveObject.scala | 1 + akka-actors/src/main/scala/actor/Actor.scala | 25 ++-- .../src/main/scala/nio/RemoteClient.scala | 3 +- .../src/main/scala/nio/RemoteServer.scala | 40 ++++-- .../EventBasedSingleThreadActorTest.scala | 2 +- .../scala/EventBasedThreadPoolActorTest.scala | 2 +- .../src/test/scala/RemoteActorTest.scala | 11 -- .../src/test/scala/ThreadBasedActorTest.scala | 2 +- akka-security/src/main/scala/Security.scala | 2 +- .../src/test/scala/SecuritySpec.scala | 6 +- .../akka/nio/protobuf/RemoteProtocol.java | 123 ++++++++++++------ .../akka/nio/protobuf/RemoteProtocol.proto | 15 +-- 12 files changed, 138 insertions(+), 94 deletions(-) diff --git a/akka-actors/src/main/scala/actor/ActiveObject.scala b/akka-actors/src/main/scala/actor/ActiveObject.scala index 983d323148..566e2a9f41 100644 --- a/akka-actors/src/main/scala/actor/ActiveObject.scala +++ b/akka-actors/src/main/scala/actor/ActiveObject.scala @@ -204,6 +204,7 @@ private[akka] sealed class ActiveObjectAspect { .setId(RemoteRequestIdFactory.nextId) .setMethod(rtti.getMethod.getName) .setTarget(target.getName) + .setUuid(actor.uuid) .setTimeout(timeout) .setIsActor(false) .setIsOneWay(oneWay_?) diff --git a/akka-actors/src/main/scala/actor/Actor.scala b/akka-actors/src/main/scala/actor/Actor.scala index de1cb5fba6..bc7a8806f3 100644 --- a/akka-actors/src/main/scala/actor/Actor.scala +++ b/akka-actors/src/main/scala/actor/Actor.scala @@ -101,13 +101,14 @@ trait Actor extends Logging with TransactionManagement { implicit val self: AnyRef = this // FIXME http://www.assembla.com/spaces/akka/tickets/56-Change-UUID-generation-for-the-TransactionManagement-trait - val uuid = Uuid.newUuid.toString - + private[akka] var _uuid = Uuid.newUuid.toString + def uuid = _uuid + // ==================================== // private fields // ==================================== - @volatile private var _isRunning: Boolean = false + @volatile private var _isRunning: Boolean = false @volatile private var _isShutDown: Boolean = false private var _hotswap: Option[PartialFunction[Any, Unit]] = None private var _config: Option[AnyRef] = None @@ -346,6 +347,9 @@ trait Actor extends Logging with TransactionManagement { "Actor has not been started, you need to invoke 'actor.start' before using it") } + /** + * Same as the '!' method but does not take an implicit sender as second parameter. + */ def send(message: AnyRef) = { if (_isRunning) postMessageToMailbox(message, None) else throw new IllegalStateException( @@ -394,17 +398,10 @@ trait Actor extends Logging with TransactionManagement { def !![T](message: AnyRef): Option[T] = !![T](message, timeout) /** - * Sends a message asynchronously, but waits on a future indefinitely. E.g. emulates a synchronous call. - *

- * NOTE: - * Should be used with care (almost never), since very dangerous (will block a thread indefinitely if no reply). + * This method is evil and have been removed. Use '!!' with a timeout instead. */ - def !?[T](message: AnyRef): T = if (_isRunning) { - val future = postMessageToMailboxAndCreateFutureResultWithTimeout(message, 0) - future.awaitBlocking - getResultOrThrowException(future).get - } else throw new IllegalStateException( - "Actor has not been started, you need to invoke 'actor.start' before using it") + def !?[T](message: AnyRef): T = throw new UnsupportedOperationException( + "'!?' is evil and have been removed. Use '!!' with a timeout instead") /** * Use reply(..) to reply with a message to the original sender of the message currently @@ -596,6 +593,7 @@ trait Actor extends Logging with TransactionManagement { .setId(RemoteRequestIdFactory.nextId) .setTarget(this.getClass.getName) .setTimeout(timeout) + .setUuid(uuid) .setIsActor(true) .setIsOneWay(true) .setIsEscaped(false) @@ -615,6 +613,7 @@ trait Actor extends Logging with TransactionManagement { .setId(RemoteRequestIdFactory.nextId) .setTarget(this.getClass.getName) .setTimeout(timeout) + .setUuid(uuid) .setIsActor(true) .setIsOneWay(false) .setIsEscaped(false) diff --git a/akka-actors/src/main/scala/nio/RemoteClient.scala b/akka-actors/src/main/scala/nio/RemoteClient.scala index 4e1a777181..06c744a37c 100644 --- a/akka-actors/src/main/scala/nio/RemoteClient.scala +++ b/akka-actors/src/main/scala/nio/RemoteClient.scala @@ -148,7 +148,8 @@ class RemoteClientHandler(val name: String, extends SimpleChannelUpstreamHandler with Logging { override def handleUpstream(ctx: ChannelHandlerContext, event: ChannelEvent) = { - if (event.isInstanceOf[ChannelStateEvent] && event.asInstanceOf[ChannelStateEvent].getState != ChannelState.INTEREST_OPS) { + if (event.isInstanceOf[ChannelStateEvent] && + event.asInstanceOf[ChannelStateEvent].getState != ChannelState.INTEREST_OPS) { log.debug(event.toString) } super.handleUpstream(ctx, event) diff --git a/akka-actors/src/main/scala/nio/RemoteServer.scala b/akka-actors/src/main/scala/nio/RemoteServer.scala index 635b231e52..23bfbfa187 100755 --- a/akka-actors/src/main/scala/nio/RemoteServer.scala +++ b/akka-actors/src/main/scala/nio/RemoteServer.scala @@ -67,7 +67,8 @@ object RemoteServer extends Logging { /** * @author Jonas Bonér */ -class RemoteServerPipelineFactory(name: String, loader: Option[ClassLoader]) extends ChannelPipelineFactory { +class RemoteServerPipelineFactory(name: String, loader: Option[ClassLoader]) + extends ChannelPipelineFactory { def getPipeline: ChannelPipeline = { val p = Channels.pipeline() p.addLast("frameDecoder", new LengthFieldBasedFrameDecoder(1048576, 0, 4, 0, 4)) @@ -83,12 +84,14 @@ class RemoteServerPipelineFactory(name: String, loader: Option[ClassLoader]) ext * @author Jonas Bonér */ @ChannelPipelineCoverage { val value = "all" } -class RemoteServerHandler(val name: String, val applicationLoader: Option[ClassLoader]) extends SimpleChannelUpstreamHandler with Logging { +class RemoteServerHandler(val name: String, val applicationLoader: Option[ClassLoader]) + extends SimpleChannelUpstreamHandler with Logging { private val activeObjects = new ConcurrentHashMap[String, AnyRef] private val actors = new ConcurrentHashMap[String, Actor] override def handleUpstream(ctx: ChannelHandlerContext, event: ChannelEvent) = { - if (event.isInstanceOf[ChannelStateEvent] && event.asInstanceOf[ChannelStateEvent].getState != ChannelState.INTEREST_OPS) { + if (event.isInstanceOf[ChannelStateEvent] && + event.asInstanceOf[ChannelStateEvent].getState != ChannelState.INTEREST_OPS) { log.debug(event.toString) } super.handleUpstream(ctx, event) @@ -96,8 +99,11 @@ class RemoteServerHandler(val name: String, val applicationLoader: Option[ClassL override def messageReceived(ctx: ChannelHandlerContext, event: MessageEvent) = { val message = event.getMessage - if (message == null) throw new IllegalStateException("Message in remote MessageEvent is null: " + event) - if (message.isInstanceOf[RemoteRequest]) handleRemoteRequest(message.asInstanceOf[RemoteRequest], event.getChannel) + if (message == null) throw new IllegalStateException( + "Message in remote MessageEvent is null: " + event) + if (message.isInstanceOf[RemoteRequest]) { + handleRemoteRequest(message.asInstanceOf[RemoteRequest], event.getChannel) + } } override def exceptionCaught(ctx: ChannelHandlerContext, event: ExceptionEvent) = { @@ -115,7 +121,7 @@ class RemoteServerHandler(val name: String, val applicationLoader: Option[ClassL private def dispatchToActor(request: RemoteRequest, channel: Channel) = { import Actor._ log.debug("Dispatching to remote actor [%s]", request.getTarget) - val actor = createActor(request.getTarget, request.getTimeout) + val actor = createActor(request.getTarget, request.getUuid, request.getTimeout) actor.start val message = RemoteProtocolBuilder.getMessage(request) if (request.getIsOneWay) actor ! message @@ -158,7 +164,8 @@ class RemoteServerHandler(val name: String, val applicationLoader: Option[ClassL //continueTransaction(request) try { - val messageReceiver = activeObject.getClass.getDeclaredMethod(request.getMethod, unescapedArgClasses: _*) + val messageReceiver = activeObject.getClass.getDeclaredMethod( + request.getMethod, unescapedArgClasses: _*) if (request.getIsOneWay) messageReceiver.invoke(activeObject, unescapedArgs: _*) else { val result = messageReceiver.invoke(activeObject, unescapedArgs: _*) @@ -174,7 +181,9 @@ class RemoteServerHandler(val name: String, val applicationLoader: Option[ClassL } } catch { case e: InvocationTargetException => - log.error("Could not invoke remote active object [%s :: %s] due to: %s", request.getMethod, request.getTarget, e.getCause) + log.error( + "Could not invoke remote active object [%s :: %s] due to: %s", + request.getMethod, request.getTarget, e.getCause) e.getCause.printStackTrace val replyBuilder = RemoteReply.newBuilder .setId(request.getId) @@ -185,7 +194,9 @@ class RemoteServerHandler(val name: String, val applicationLoader: Option[ClassL val replyMessage = replyBuilder.build channel.write(replyMessage) case e: Throwable => - log.error("Could not invoke remote active object [%s :: %s] due to: %s", request.getMethod, request.getTarget, e) + log.error( + "Could not invoke remote active object [%s :: %s] due to: %s", + request.getMethod, request.getTarget, e) e.printStackTrace val replyBuilder = RemoteReply.newBuilder .setId(request.getId) @@ -250,21 +261,22 @@ class RemoteServerHandler(val name: String, val applicationLoader: Option[ClassL } else activeObjectOrNull } - private def createActor(name: String, timeout: Long): Actor = { - val actorOrNull = actors.get(name) + private def createActor(name: String, uuid: String, timeout: Long): Actor = { + val actorOrNull = actors.get(uuid) if (actorOrNull == null) { try { - log.info("Creating a new remote actor [%s]", name) + log.info("Creating a new remote actor [%s:%s]", name, uuid) val clazz = if (applicationLoader.isDefined) applicationLoader.get.loadClass(name) else Class.forName(name) val newInstance = clazz.newInstance.asInstanceOf[Actor] + newInstance._uuid = uuid newInstance.timeout = timeout newInstance._remoteAddress = None - actors.put(name, newInstance) + actors.put(uuid, newInstance) newInstance } catch { case e => - log.debug("Could not create remote actor instance due to: %s", e) + log.error(e, "Could not create remote actor instance due to: " + e.getMessage) e.printStackTrace throw e } diff --git a/akka-actors/src/test/scala/EventBasedSingleThreadActorTest.scala b/akka-actors/src/test/scala/EventBasedSingleThreadActorTest.scala index bd7389e676..46661e3b97 100644 --- a/akka-actors/src/test/scala/EventBasedSingleThreadActorTest.scala +++ b/akka-actors/src/test/scala/EventBasedSingleThreadActorTest.scala @@ -41,7 +41,7 @@ class EventBasedSingleThreadActorTest extends JUnitSuite { implicit val timeout = 5000L val actor = new TestActor actor.start - val result: String = actor !? "Hello" + val result: String = (actor !! ("Hello", 10000)).get assert("World" === result) actor.stop } diff --git a/akka-actors/src/test/scala/EventBasedThreadPoolActorTest.scala b/akka-actors/src/test/scala/EventBasedThreadPoolActorTest.scala index 55345ec25e..2030942b7a 100644 --- a/akka-actors/src/test/scala/EventBasedThreadPoolActorTest.scala +++ b/akka-actors/src/test/scala/EventBasedThreadPoolActorTest.scala @@ -37,7 +37,7 @@ class EventBasedThreadPoolActorTest extends JUnitSuite { implicit val timeout = 5000L val actor = new TestActor actor.start - val result: String = actor !? "Hello" + val result: String = (actor !! ("Hello", 10000)).get assert("World" === result) actor.stop } diff --git a/akka-actors/src/test/scala/RemoteActorTest.scala b/akka-actors/src/test/scala/RemoteActorTest.scala index bea33a50d9..191898269b 100644 --- a/akka-actors/src/test/scala/RemoteActorTest.scala +++ b/akka-actors/src/test/scala/RemoteActorTest.scala @@ -50,17 +50,6 @@ class RemoteActorTest extends JUnitSuite { actor.stop } - @Test - def shouldSendReplySync = { - implicit val timeout = 500000000L - val actor = new RemoteActorSpecActorBidirectional - actor.makeRemote(RemoteServer.HOSTNAME, RemoteServer.PORT) - actor.start - val result: String = actor !? "Hello" - assert("World" === result) - actor.stop - } - @Test def shouldSendReplyAsync = { implicit val timeout = 500000000L diff --git a/akka-actors/src/test/scala/ThreadBasedActorTest.scala b/akka-actors/src/test/scala/ThreadBasedActorTest.scala index dca6634acc..335a6f461b 100644 --- a/akka-actors/src/test/scala/ThreadBasedActorTest.scala +++ b/akka-actors/src/test/scala/ThreadBasedActorTest.scala @@ -41,7 +41,7 @@ class ThreadBasedActorTest extends JUnitSuite { implicit val timeout = 5000L val actor = new TestActor actor.start - val result: String = actor !? "Hello" + val result: String = (actor !! ("Hello", 10000)).get assert("World" === result) actor.stop } diff --git a/akka-security/src/main/scala/Security.scala b/akka-security/src/main/scala/Security.scala index c8964cb506..384af1ea20 100644 --- a/akka-security/src/main/scala/Security.scala +++ b/akka-security/src/main/scala/Security.scala @@ -86,7 +86,7 @@ class AkkaSecurityFilterFactory extends ResourceFilterFactory with Logging { override def filter(request: ContainerRequest): ContainerRequest = rolesAllowed match { case Some(roles) => { - (authenticator !? Authenticate(request, roles)).asInstanceOf[AnyRef] match { + (authenticator !! (Authenticate(request, roles), 10000)).get.asInstanceOf[AnyRef] match { case OK => request case r if r.isInstanceOf[Response] => throw new WebApplicationException(r.asInstanceOf[Response]) diff --git a/akka-security/src/test/scala/SecuritySpec.scala b/akka-security/src/test/scala/SecuritySpec.scala index 880f26693c..feabd8f474 100644 --- a/akka-security/src/test/scala/SecuritySpec.scala +++ b/akka-security/src/test/scala/SecuritySpec.scala @@ -26,7 +26,7 @@ class BasicAuthenticatorSpec extends junit.framework.TestCase @Test def testChallenge = { val req = mock[ContainerRequest] - val result: Response = (authenticator !? Authenticate(req, List("foo"))) + val result: Response = (authenticator !! (Authenticate(req, List("foo")), 10000)).get // the actor replies with a challenge for the browser result.getStatus must equal(Response.Status.UNAUTHORIZED.getStatusCode) @@ -41,7 +41,7 @@ class BasicAuthenticatorSpec extends junit.framework.TestCase // fake a request authorization -> this will authorize the user when(req.isUserInRole("chef")).thenReturn(true) - val result: AnyRef = (authenticator !? Authenticate(req, List("chef"))) + val result: AnyRef = (authenticator !! (Authenticate(req, List("chef")), 10000)).get result must be(OK) // the authenticator must have set a security context @@ -55,7 +55,7 @@ class BasicAuthenticatorSpec extends junit.framework.TestCase when(req.getHeaderValue("Authorization")).thenReturn("Basic " + new String(Base64.encode("foo:bar"))) when(req.isUserInRole("chef")).thenReturn(false) // this will deny access - val result: Response = (authenticator !? Authenticate(req, List("chef"))) + val result: Response = (authenticator !! (Authenticate(req, List("chef")), 10000)).get result.getStatus must equal(Response.Status.FORBIDDEN.getStatusCode) diff --git a/akka-util-java/src/main/java/se/scalablesolutions/akka/nio/protobuf/RemoteProtocol.java b/akka-util-java/src/main/java/se/scalablesolutions/akka/nio/protobuf/RemoteProtocol.java index b956e77c96..950cfeb918 100644 --- a/akka-util-java/src/main/java/se/scalablesolutions/akka/nio/protobuf/RemoteProtocol.java +++ b/akka-util-java/src/main/java/se/scalablesolutions/akka/nio/protobuf/RemoteProtocol.java @@ -73,36 +73,43 @@ public final class RemoteProtocol { public boolean hasTarget() { return hasTarget; } public java.lang.String getTarget() { return target_; } - // required uint64 timeout = 7; - public static final int TIMEOUT_FIELD_NUMBER = 7; + // required string uuid = 7; + public static final int UUID_FIELD_NUMBER = 7; + private boolean hasUuid; + private java.lang.String uuid_ = ""; + public boolean hasUuid() { return hasUuid; } + public java.lang.String getUuid() { return uuid_; } + + // required uint64 timeout = 8; + public static final int TIMEOUT_FIELD_NUMBER = 8; private boolean hasTimeout; private long timeout_ = 0L; public boolean hasTimeout() { return hasTimeout; } public long getTimeout() { return timeout_; } - // optional string supervisorUuid = 8; - public static final int SUPERVISORUUID_FIELD_NUMBER = 8; + // optional string supervisorUuid = 9; + public static final int SUPERVISORUUID_FIELD_NUMBER = 9; private boolean hasSupervisorUuid; private java.lang.String supervisorUuid_ = ""; public boolean hasSupervisorUuid() { return hasSupervisorUuid; } public java.lang.String getSupervisorUuid() { return supervisorUuid_; } - // required bool isActor = 9; - public static final int ISACTOR_FIELD_NUMBER = 9; + // required bool isActor = 10; + public static final int ISACTOR_FIELD_NUMBER = 10; private boolean hasIsActor; private boolean isActor_ = false; public boolean hasIsActor() { return hasIsActor; } public boolean getIsActor() { return isActor_; } - // required bool isOneWay = 10; - public static final int ISONEWAY_FIELD_NUMBER = 10; + // required bool isOneWay = 11; + public static final int ISONEWAY_FIELD_NUMBER = 11; private boolean hasIsOneWay; private boolean isOneWay_ = false; public boolean hasIsOneWay() { return hasIsOneWay; } public boolean getIsOneWay() { return isOneWay_; } - // required bool isEscaped = 11; - public static final int ISESCAPED_FIELD_NUMBER = 11; + // required bool isEscaped = 12; + public static final int ISESCAPED_FIELD_NUMBER = 12; private boolean hasIsEscaped; private boolean isEscaped_ = false; public boolean hasIsEscaped() { return hasIsEscaped; } @@ -113,6 +120,7 @@ public final class RemoteProtocol { if (!hasProtocol) return false; if (!hasMessage) return false; if (!hasTarget) return false; + if (!hasUuid) return false; if (!hasTimeout) return false; if (!hasIsActor) return false; if (!hasIsOneWay) return false; @@ -140,20 +148,23 @@ public final class RemoteProtocol { if (hasTarget()) { output.writeString(6, getTarget()); } + if (hasUuid()) { + output.writeString(7, getUuid()); + } if (hasTimeout()) { - output.writeUInt64(7, getTimeout()); + output.writeUInt64(8, getTimeout()); } if (hasSupervisorUuid()) { - output.writeString(8, getSupervisorUuid()); + output.writeString(9, getSupervisorUuid()); } if (hasIsActor()) { - output.writeBool(9, getIsActor()); + output.writeBool(10, getIsActor()); } if (hasIsOneWay()) { - output.writeBool(10, getIsOneWay()); + output.writeBool(11, getIsOneWay()); } if (hasIsEscaped()) { - output.writeBool(11, getIsEscaped()); + output.writeBool(12, getIsEscaped()); } getUnknownFields().writeTo(output); } @@ -188,25 +199,29 @@ public final class RemoteProtocol { size += com.google.protobuf.CodedOutputStream .computeStringSize(6, getTarget()); } + if (hasUuid()) { + size += com.google.protobuf.CodedOutputStream + .computeStringSize(7, getUuid()); + } if (hasTimeout()) { size += com.google.protobuf.CodedOutputStream - .computeUInt64Size(7, getTimeout()); + .computeUInt64Size(8, getTimeout()); } if (hasSupervisorUuid()) { size += com.google.protobuf.CodedOutputStream - .computeStringSize(8, getSupervisorUuid()); + .computeStringSize(9, getSupervisorUuid()); } if (hasIsActor()) { size += com.google.protobuf.CodedOutputStream - .computeBoolSize(9, getIsActor()); + .computeBoolSize(10, getIsActor()); } if (hasIsOneWay()) { size += com.google.protobuf.CodedOutputStream - .computeBoolSize(10, getIsOneWay()); + .computeBoolSize(11, getIsOneWay()); } if (hasIsEscaped()) { size += com.google.protobuf.CodedOutputStream - .computeBoolSize(11, getIsEscaped()); + .computeBoolSize(12, getIsEscaped()); } size += getUnknownFields().getSerializedSize(); memoizedSerializedSize = size; @@ -375,6 +390,9 @@ public final class RemoteProtocol { if (other.hasTarget()) { setTarget(other.getTarget()); } + if (other.hasUuid()) { + setUuid(other.getUuid()); + } if (other.hasTimeout()) { setTimeout(other.getTimeout()); } @@ -439,23 +457,27 @@ public final class RemoteProtocol { setTarget(input.readString()); break; } - case 56: { + case 58: { + setUuid(input.readString()); + break; + } + case 64: { setTimeout(input.readUInt64()); break; } - case 66: { + case 74: { setSupervisorUuid(input.readString()); break; } - case 72: { + case 80: { setIsActor(input.readBool()); break; } - case 80: { + case 88: { setIsOneWay(input.readBool()); break; } - case 88: { + case 96: { setIsEscaped(input.readBool()); break; } @@ -584,7 +606,28 @@ public final class RemoteProtocol { return this; } - // required uint64 timeout = 7; + // required string uuid = 7; + public boolean hasUuid() { + return result.hasUuid(); + } + public java.lang.String getUuid() { + return result.getUuid(); + } + public Builder setUuid(java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + result.hasUuid = true; + result.uuid_ = value; + return this; + } + public Builder clearUuid() { + result.hasUuid = false; + result.uuid_ = getDefaultInstance().getUuid(); + return this; + } + + // required uint64 timeout = 8; public boolean hasTimeout() { return result.hasTimeout(); } @@ -602,7 +645,7 @@ public final class RemoteProtocol { return this; } - // optional string supervisorUuid = 8; + // optional string supervisorUuid = 9; public boolean hasSupervisorUuid() { return result.hasSupervisorUuid(); } @@ -623,7 +666,7 @@ public final class RemoteProtocol { return this; } - // required bool isActor = 9; + // required bool isActor = 10; public boolean hasIsActor() { return result.hasIsActor(); } @@ -641,7 +684,7 @@ public final class RemoteProtocol { return this; } - // required bool isOneWay = 10; + // required bool isOneWay = 11; public boolean hasIsOneWay() { return result.hasIsOneWay(); } @@ -659,7 +702,7 @@ public final class RemoteProtocol { return this; } - // required bool isEscaped = 11; + // required bool isEscaped = 12; public boolean hasIsEscaped() { return result.hasIsEscaped(); } @@ -1263,17 +1306,17 @@ public final class RemoteProtocol { java.lang.String[] descriptorData = { "\n;se/scalablesolutions/akka/nio/protobuf" + "/RemoteProtocol.proto\022&se.scalablesoluti" + - "ons.akka.nio.protobuf\"\326\001\n\rRemoteRequest\022" + + "ons.akka.nio.protobuf\"\344\001\n\rRemoteRequest\022" + "\n\n\002id\030\001 \002(\004\022\020\n\010protocol\030\002 \002(\r\022\017\n\007message" + "\030\003 \002(\014\022\027\n\017messageManifest\030\004 \001(\014\022\016\n\006metho" + - "d\030\005 \001(\t\022\016\n\006target\030\006 \002(\t\022\017\n\007timeout\030\007 \002(\004" + - "\022\026\n\016supervisorUuid\030\010 \001(\t\022\017\n\007isActor\030\t \002(" + - "\010\022\020\n\010isOneWay\030\n \002(\010\022\021\n\tisEscaped\030\013 \002(\010\"\247" + - "\001\n\013RemoteReply\022\n\n\002id\030\001 \002(\004\022\020\n\010protocol\030\002" + - " \001(\r\022\017\n\007message\030\003 \001(\014\022\027\n\017messageManifest", - "\030\004 \001(\014\022\021\n\texception\030\005 \001(\t\022\026\n\016supervisorU" + - "uid\030\006 \001(\t\022\017\n\007isActor\030\007 \002(\010\022\024\n\014isSuccessf" + - "ul\030\010 \002(\010B\002H\001" + "d\030\005 \001(\t\022\016\n\006target\030\006 \002(\t\022\014\n\004uuid\030\007 \002(\t\022\017\n" + + "\007timeout\030\010 \002(\004\022\026\n\016supervisorUuid\030\t \001(\t\022\017" + + "\n\007isActor\030\n \002(\010\022\020\n\010isOneWay\030\013 \002(\010\022\021\n\tisE" + + "scaped\030\014 \002(\010\"\247\001\n\013RemoteReply\022\n\n\002id\030\001 \002(\004" + + "\022\020\n\010protocol\030\002 \001(\r\022\017\n\007message\030\003 \001(\014\022\027\n\017m", + "essageManifest\030\004 \001(\014\022\021\n\texception\030\005 \001(\t\022" + + "\026\n\016supervisorUuid\030\006 \001(\t\022\017\n\007isActor\030\007 \002(\010" + + "\022\024\n\014isSuccessful\030\010 \002(\010" }; com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner = new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() { @@ -1285,7 +1328,7 @@ public final class RemoteProtocol { internal_static_se_scalablesolutions_akka_nio_protobuf_RemoteRequest_fieldAccessorTable = new com.google.protobuf.GeneratedMessage.FieldAccessorTable( internal_static_se_scalablesolutions_akka_nio_protobuf_RemoteRequest_descriptor, - new java.lang.String[] { "Id", "Protocol", "Message", "MessageManifest", "Method", "Target", "Timeout", "SupervisorUuid", "IsActor", "IsOneWay", "IsEscaped", }, + new java.lang.String[] { "Id", "Protocol", "Message", "MessageManifest", "Method", "Target", "Uuid", "Timeout", "SupervisorUuid", "IsActor", "IsOneWay", "IsEscaped", }, se.scalablesolutions.akka.nio.protobuf.RemoteProtocol.RemoteRequest.class, se.scalablesolutions.akka.nio.protobuf.RemoteProtocol.RemoteRequest.Builder.class); internal_static_se_scalablesolutions_akka_nio_protobuf_RemoteReply_descriptor = diff --git a/akka-util-java/src/main/java/se/scalablesolutions/akka/nio/protobuf/RemoteProtocol.proto b/akka-util-java/src/main/java/se/scalablesolutions/akka/nio/protobuf/RemoteProtocol.proto index 148b3960ae..1248339b3f 100644 --- a/akka-util-java/src/main/java/se/scalablesolutions/akka/nio/protobuf/RemoteProtocol.proto +++ b/akka-util-java/src/main/java/se/scalablesolutions/akka/nio/protobuf/RemoteProtocol.proto @@ -1,7 +1,7 @@ /** * Copyright (C) 2009 Scalable Solutions. */ - + package se.scalablesolutions.akka.nio.protobuf; /* @@ -10,8 +10,6 @@ package se.scalablesolutions.akka.nio.protobuf; protoc se/scalablesolutions/akka/nio/protobuf/RemoteProtocol.proto --java_out . */ -option optimize_for = SPEED; - message RemoteRequest { required uint64 id = 1; required uint32 protocol = 2; @@ -19,11 +17,12 @@ message RemoteRequest { optional bytes messageManifest = 4; optional string method = 5; required string target = 6; - required uint64 timeout = 7; - optional string supervisorUuid = 8; - required bool isActor = 9; - required bool isOneWay = 10; - required bool isEscaped = 11; + required string uuid = 7; + required uint64 timeout = 8; + optional string supervisorUuid = 9; + required bool isActor = 10; + required bool isOneWay = 11; + required bool isEscaped = 12; } message RemoteReply { From 7e842bdb92d745412a3ad2516f117e48fb6bfc53 Mon Sep 17 00:00:00 2001 From: jboner Date: Sat, 21 Nov 2009 22:04:10 +0100 Subject: [PATCH 06/20] Added zlib compression to remote actors --- .../src/main/scala/nio/RemoteClient.scala | 3 +++ .../src/main/scala/nio/RemoteServer.scala | 20 +++++++++++-------- akka-kernel/pom.xml | 2 +- config/akka-reference.conf | 1 + 4 files changed, 17 insertions(+), 9 deletions(-) diff --git a/akka-actors/src/main/scala/nio/RemoteClient.scala b/akka-actors/src/main/scala/nio/RemoteClient.scala index 06c744a37c..a77e975bcc 100644 --- a/akka-actors/src/main/scala/nio/RemoteClient.scala +++ b/akka-actors/src/main/scala/nio/RemoteClient.scala @@ -22,6 +22,7 @@ import org.jboss.netty.util.{TimerTask, Timeout, HashedWheelTimer} import java.net.InetSocketAddress import java.util.concurrent.{TimeUnit, Executors, ConcurrentMap, ConcurrentHashMap} +import org.jboss.netty.handler.codec.compression.{ZlibDecoder, ZlibEncoder} /** * @author Jonas Bonér @@ -128,8 +129,10 @@ class RemoteClientPipelineFactory(name: String, def getPipeline: ChannelPipeline = { val pipeline = Channels.pipeline() pipeline.addLast("timeout", new ReadTimeoutHandler(RemoteClient.TIMER, RemoteClient.READ_TIMEOUT)) + if (RemoteServer.COMPRESSION) pipeline.addLast("zlibDecoder", new ZlibDecoder()) pipeline.addLast("frameDecoder", new LengthFieldBasedFrameDecoder(1048576, 0, 4, 0, 4)) pipeline.addLast("protobufDecoder", new ProtobufDecoder(RemoteReply.getDefaultInstance)) + if (RemoteServer.COMPRESSION) pipeline.addLast("zlibEncoder", new ZlibEncoder()) pipeline.addLast("frameEncoder", new LengthFieldPrepender(4)) pipeline.addLast("protobufEncoder", new ProtobufEncoder()) pipeline.addLast("handler", new RemoteClientHandler(name, futures, supervisors, bootstrap)) diff --git a/akka-actors/src/main/scala/nio/RemoteServer.scala b/akka-actors/src/main/scala/nio/RemoteServer.scala index 23bfbfa187..6534d2b93c 100755 --- a/akka-actors/src/main/scala/nio/RemoteServer.scala +++ b/akka-actors/src/main/scala/nio/RemoteServer.scala @@ -18,6 +18,7 @@ import org.jboss.netty.channel._ import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory import org.jboss.netty.handler.codec.frame.{LengthFieldBasedFrameDecoder, LengthFieldPrepender} import org.jboss.netty.handler.codec.protobuf.{ProtobufDecoder, ProtobufEncoder} +import org.jboss.netty.handler.codec.compression.{ZlibEncoder, ZlibDecoder} /** * @author Jonas Bonér @@ -25,7 +26,8 @@ import org.jboss.netty.handler.codec.protobuf.{ProtobufDecoder, ProtobufEncoder} object RemoteServer extends Logging { val HOSTNAME = config.getString("akka.remote.server.hostname", "localhost") val PORT = config.getInt("akka.remote.server.port", 9999) - val CONNECTION_TIMEOUT_MILLIS = config.getInt("akka.remote.server.connection-timeout", 1000) + val COMPRESSION = config.getBool("akka.remote.compression", true) + val CONNECTION_TIMEOUT_MILLIS = config.getInt("akka.remote.server.connection-timeout", 1000) private var hostname = HOSTNAME private var port = PORT @@ -70,13 +72,15 @@ object RemoteServer extends Logging { class RemoteServerPipelineFactory(name: String, loader: Option[ClassLoader]) extends ChannelPipelineFactory { def getPipeline: ChannelPipeline = { - val p = Channels.pipeline() - p.addLast("frameDecoder", new LengthFieldBasedFrameDecoder(1048576, 0, 4, 0, 4)) - p.addLast("protobufDecoder", new ProtobufDecoder(RemoteRequest.getDefaultInstance)) - p.addLast("frameEncoder", new LengthFieldPrepender(4)) - p.addLast("protobufEncoder", new ProtobufEncoder) - p.addLast("handler", new RemoteServerHandler(name, loader)) - p + val pipeline = Channels.pipeline() + if (RemoteServer.COMPRESSION) pipeline.addLast("zlibDecoder", new ZlibDecoder()) + pipeline.addLast("frameDecoder", new LengthFieldBasedFrameDecoder(1048576, 0, 4, 0, 4)) + pipeline.addLast("protobufDecoder", new ProtobufDecoder(RemoteRequest.getDefaultInstance)) + if (RemoteServer.COMPRESSION) pipeline.addLast("zlibEncoder", new ZlibEncoder()) + pipeline.addLast("frameEncoder", new LengthFieldPrepender(4)) + pipeline.addLast("protobufEncoder", new ProtobufEncoder) + pipeline.addLast("handler", new RemoteServerHandler(name, loader)) + pipeline } } diff --git a/akka-kernel/pom.xml b/akka-kernel/pom.xml index b964967624..6e430c08c6 100755 --- a/akka-kernel/pom.xml +++ b/akka-kernel/pom.xml @@ -87,7 +87,7 @@ org.jboss.netty netty - 3.1.0.GA + 3.2.0.ALPHA1 org.apache diff --git a/config/akka-reference.conf b/config/akka-reference.conf index a4e42a267a..c6fbb75cb4 100644 --- a/config/akka-reference.conf +++ b/config/akka-reference.conf @@ -37,6 +37,7 @@ + compression = on # turn on/off zlib compression service = on hostname = "localhost" From 08cf576225ab6ef71b5fea493309977667d00ef8 Mon Sep 17 00:00:00 2001 From: jboner Date: Sun, 22 Nov 2009 14:32:27 +0100 Subject: [PATCH 07/20] added compression level config options --- akka-actors/pom.xml | 5 +++++ .../src/main/scala/nio/RemoteClient.scala | 12 +++++++++-- .../src/main/scala/nio/RemoteServer.scala | 21 ++++++++++++++++--- config/akka-reference.conf | 17 +++++++-------- 4 files changed, 41 insertions(+), 14 deletions(-) diff --git a/akka-actors/pom.xml b/akka-actors/pom.xml index 5138a48ccb..30362fefff 100644 --- a/akka-actors/pom.xml +++ b/akka-actors/pom.xml @@ -74,6 +74,11 @@ + + org.h2.compress + h2-lzf + 1.0 + org.codehaus.jackson jackson-core-asl diff --git a/akka-actors/src/main/scala/nio/RemoteClient.scala b/akka-actors/src/main/scala/nio/RemoteClient.scala index a77e975bcc..99872beb33 100644 --- a/akka-actors/src/main/scala/nio/RemoteClient.scala +++ b/akka-actors/src/main/scala/nio/RemoteClient.scala @@ -129,10 +129,18 @@ class RemoteClientPipelineFactory(name: String, def getPipeline: ChannelPipeline = { val pipeline = Channels.pipeline() pipeline.addLast("timeout", new ReadTimeoutHandler(RemoteClient.TIMER, RemoteClient.READ_TIMEOUT)) - if (RemoteServer.COMPRESSION) pipeline.addLast("zlibDecoder", new ZlibDecoder()) + RemoteServer.COMPRESSION_SCHEME match { + case "zlib" => pipeline.addLast("zlibDecoder", new ZlibDecoder) + //case "lzf" => pipeline.addLast("lzfDecoder", new LzfDecoder) + case _ => {} // no compression + } pipeline.addLast("frameDecoder", new LengthFieldBasedFrameDecoder(1048576, 0, 4, 0, 4)) pipeline.addLast("protobufDecoder", new ProtobufDecoder(RemoteReply.getDefaultInstance)) - if (RemoteServer.COMPRESSION) pipeline.addLast("zlibEncoder", new ZlibEncoder()) + RemoteServer.COMPRESSION_SCHEME match { + case "zlib" => pipeline.addLast("zlibEncoder", new ZlibEncoder(RemoteServer.ZLIB_COMPRESSION_LEVEL)) + //case "lzf" => pipeline.addLast("lzfEncoder", new LzfEncoder) + case _ => {} // no compression + } pipeline.addLast("frameEncoder", new LengthFieldPrepender(4)) pipeline.addLast("protobufEncoder", new ProtobufEncoder()) pipeline.addLast("handler", new RemoteClientHandler(name, futures, supervisors, bootstrap)) diff --git a/akka-actors/src/main/scala/nio/RemoteServer.scala b/akka-actors/src/main/scala/nio/RemoteServer.scala index 6534d2b93c..c9528dc6a4 100755 --- a/akka-actors/src/main/scala/nio/RemoteServer.scala +++ b/akka-actors/src/main/scala/nio/RemoteServer.scala @@ -26,7 +26,14 @@ import org.jboss.netty.handler.codec.compression.{ZlibEncoder, ZlibDecoder} object RemoteServer extends Logging { val HOSTNAME = config.getString("akka.remote.server.hostname", "localhost") val PORT = config.getInt("akka.remote.server.port", 9999) - val COMPRESSION = config.getBool("akka.remote.compression", true) + val COMPRESSION_SCHEME = config.getString("akka.remote.compression-scheme", "zlib") + val ZLIB_COMPRESSION_LEVEL = { + val level = config.getInt("akka.remote.zlib-compression-level", 6) + if (level < 1 && level > 9) throw new IllegalArgumentException( + "zlib compression level has to be within 1-9, with 1 being fastest and 9 being the most compressed") + level + } + val CONNECTION_TIMEOUT_MILLIS = config.getInt("akka.remote.server.connection-timeout", 1000) private var hostname = HOSTNAME @@ -73,10 +80,18 @@ class RemoteServerPipelineFactory(name: String, loader: Option[ClassLoader]) extends ChannelPipelineFactory { def getPipeline: ChannelPipeline = { val pipeline = Channels.pipeline() - if (RemoteServer.COMPRESSION) pipeline.addLast("zlibDecoder", new ZlibDecoder()) + RemoteServer.COMPRESSION_SCHEME match { + case "zlib" => pipeline.addLast("zlibDecoder", new ZlibDecoder) + //case "lzf" => pipeline.addLast("lzfDecoder", new LzfDecoder) + case _ => {} // no compression + } pipeline.addLast("frameDecoder", new LengthFieldBasedFrameDecoder(1048576, 0, 4, 0, 4)) pipeline.addLast("protobufDecoder", new ProtobufDecoder(RemoteRequest.getDefaultInstance)) - if (RemoteServer.COMPRESSION) pipeline.addLast("zlibEncoder", new ZlibEncoder()) + RemoteServer.COMPRESSION_SCHEME match { + case "zlib" => pipeline.addLast("zlibEncoder", new ZlibEncoder(RemoteServer.ZLIB_COMPRESSION_LEVEL)) + //case "lzf" => pipeline.addLast("lzfEncoder", new LzfEncoder) + case _ => {} // no compression + } pipeline.addLast("frameEncoder", new LengthFieldPrepender(4)) pipeline.addLast("protobufEncoder", new ProtobufEncoder) pipeline.addLast("handler", new RemoteServerHandler(name, loader)) diff --git a/config/akka-reference.conf b/config/akka-reference.conf index c6fbb75cb4..8ca35927e9 100644 --- a/config/akka-reference.conf +++ b/config/akka-reference.conf @@ -22,28 +22,26 @@ boot = ["sample.java.Boot", "sample.scala.Boot", "se.scalablesolutions.akka.security.samples.Boot"] - timeout = 5000 # default timeout for future based invocations - serialize-messages = off # does a deep clone of (non-primitive) messages to ensure immutability + timeout = 5000 # default timeout for future based invocations + serialize-messages = off # does a deep clone of (non-primitive) messages to ensure immutability service = on - max-nr-of-retries = 10 - restart-on-collision = off # (not implemented yet) if 'on' then it reschedules the transaction, - # if 'off' then throws an exception or rollback for user to handle - wait-for-completion = 1000 # how long time in millis a transaction should be given time to complete when a collision is detected - wait-nr-of-times = 3 # the number of times it should check for completion of a pending transaction upon collision - distributed = off # not implemented yet + distributed = off # not implemented yet - compression = on # turn on/off zlib compression + compression-scheme = "zlib" # Options: "zlib" (lzf to come), leave out for no compression + zlib-compression-level = 6 # Options: 0-9 (1 being fastest and 9 being the most compressed), default is 6 + service = on hostname = "localhost" port = 9999 connection-timeout = 1000 # in millis (1 sec default) + reconnect-delay = 5000 # in millis (5 sec default) read-timeout = 10000 # in millis (10 sec default) @@ -65,6 +63,7 @@ storage-format = "scala-json" # Options: java, scala-json, java-json, protobuf consistency-level = "QUORUM" # Options: ZERO, ONE, QUORUM, ALL + hostname = "127.0.0.1" # IP address or hostname of the MongoDB DB instance port = 27017 From 39dcb0f7e37eefcee9eddfb8a03165c36aba5594 Mon Sep 17 00:00:00 2001 From: jboner Date: Sun, 22 Nov 2009 14:33:14 +0100 Subject: [PATCH 08/20] added support for LZF compression --- .../src/main/scala/nio/LzfCompression.scala | 29 ++++++++++++++++++ .../org/h2/compress/h2-lzf/1.0/h2-lzf-1.0.jar | Bin 0 -> 5067 bytes .../compress/h2-lzf/maven-metadata-local.xml | 12 ++++++++ 3 files changed, 41 insertions(+) create mode 100644 akka-actors/src/main/scala/nio/LzfCompression.scala create mode 100644 embedded-repo/org/h2/compress/h2-lzf/1.0/h2-lzf-1.0.jar create mode 100644 embedded-repo/org/h2/compress/h2-lzf/maven-metadata-local.xml diff --git a/akka-actors/src/main/scala/nio/LzfCompression.scala b/akka-actors/src/main/scala/nio/LzfCompression.scala new file mode 100644 index 0000000000..d69e9856ee --- /dev/null +++ b/akka-actors/src/main/scala/nio/LzfCompression.scala @@ -0,0 +1,29 @@ +/** + * Copyright (C) 2009 Scalable Solutions. + */ + +package se.scalablesolutions.akka.nio + +import org.h2.compress.{LZFInputStream, LZFOutputStream} + +import org.jboss.netty.channel.{Channel, ChannelHandlerContext, ChannelPipelineCoverage} +import org.jboss.netty.buffer.{ChannelBufferOutputStream, ChannelBufferInputStream, ChannelBuffer} +import org.jboss.netty.handler.codec.oneone.{OneToOneEncoder, OneToOneDecoder}; + +@ChannelPipelineCoverage("all") +class LzfDecoder extends OneToOneDecoder { + override protected def decode(ctx: ChannelHandlerContext, channel: Channel, message: AnyRef) = { + if (!(message.isInstanceOf[ChannelBuffer])) message + else { + new LZFInputStream(new ChannelBufferInputStream(message.asInstanceOf[ChannelBuffer])) + } + } +} + +@ChannelPipelineCoverage("all") +class LzfEncoder extends OneToOneEncoder { + override protected def encode(ctx: ChannelHandlerContext, channel: Channel, message: AnyRef) = { + if (!(message.isInstanceOf[ChannelBuffer])) message + else new LZFOutputStream(new ChannelBufferOutputStream(message.asInstanceOf[ChannelBuffer])) + } +} diff --git a/embedded-repo/org/h2/compress/h2-lzf/1.0/h2-lzf-1.0.jar b/embedded-repo/org/h2/compress/h2-lzf/1.0/h2-lzf-1.0.jar new file mode 100644 index 0000000000000000000000000000000000000000..620cfb1371e4510bf524bf16b3f6b172830f5cb5 GIT binary patch literal 5067 zcmWIWW@Zs#;9%fjIBZg4&42_r8CV#6T|*poJ^kGD|D9rBU}gyLX6FE@U;+^g3=Ft6 zi!d-CH2XUGdAhj=;t&@$m-et6XrAA@hkr@gu!i^o# zuHB6;AC*5h|2TcbCE2Iv-@zFY!oEC#^)qHjOgs1a-c-YOm%k7DtKa>e^WF0KyyAPs z_kL%-Ywl-QPDJlFblL(HCA3P;^E-(A_@={&dXEX(4p8#kBM zrziLuH!`)b`kp+JU^T_#J2`~9Zr+%%Vz<6mL0+HwqnElY?q9p+vMkk}x=Wa2pUi9+VzIiEH z^ZLHt*0c2Z+E|fga5jF`z1^k?qFzc?XChYf#e^QQkgE&5?ZL19n?2~Fh@Ura2nToveG}PUr?UI31fKzW#K8iTnPJkG{nl5@KxF@1ODS%uV0WmwjZ@oIut6 zo%dJe3zamAw{T7Ki;g_INof0%l}ooN$M{DdFWPu_!PBxBV>#|ApFdYf-{cs`nu zb<^3s|GJ|3?cS^p*p;<+hTR?0`)m5n{&?^y?etBbhvkWu(red*(p%pYg$fSeXJrg?Nv2~9<&bwim)6Sjtd@(KXmB_KI)2i`KZv|Er zxK8OvuNa?&~&TtPn_bF4ylcI4!u?V%fmA* za>b$CopYyY`aC?hpy%bGEoYx*%N(2GdGn?Gu`_cn_#N2prIF0V>Dwv8&83^0Y0Tw$ z{g}zCRjF@JzMS9s@}iN($<4g|c3M8QJ6=Z^bgLFmiK{ujYfqD}(&hsR-;J2`UR>2W zyV7rE@iIFn+2ECr+oW&axvAr`?w!S)$ebk6b`2B%s}=8F?DtWb-TiO*p0{>-8?2vt zzbjoZ^|#r9&z1cC5z^&1&3;^Lyn5rD?7n8}^^?n+_Usbhy-_%J2Y=z4L#KN--Dv*4 zQCz&xe%~Rxm_v0nr+eND9@2ktEWcwylZNCAMgF8MJbP0fGMFx$e{13bg-KiZnMDpe zN;!4)B~0j3@;z?oviyU>++!TR2~*BJP_$}q&lKvv;A-PF|FPjOss78VJs0~cn)DuP z&N_6NwI#iRuTfWHmXo3GnUm6&-KQj5FLHaP5fZ6%N_)Abr*m`sVXsO2H%;`q&)sfH zPZNEf@6T87{?wZ7%7gV1+6vWHy1w%Q*g~CFzu2@T=%}6dyx$9!aO5Wax~{Xcby@$X z2O0B@wpVVsY$H7Dg6%Dft{swTwWXe?Ofx1wnXw`6*V*4M^tZ57X$QyS!_1$4@3-7!=e%l|&l;5np z)nUFuF8|iu4IEO-0-TNpuUN(#{^5=MA5U4+&Gx;j-&#-Z7y9j1BYoQr7>h z|FM9ollm&leI=|646dBW)d_kLu7IZq&o6?M;Jy=1`yFx+Y5O0X#m&(q9#YY?X(MNJ zc!x>mB@dpq)^%BPr%bwZu*|?_Hn;qNcB6SK#b=#4dFK0b`|UsfRQ+c#ICS7xYp-`x zp}Fz|{|x_>uoVWu-3E8Nq;@;3VC|n*Cv<;&V|lP`B*yBWcqCzp}0w0PU)X+`#%f6_qXI?>RNpML~YGSS)xVo$j zi7ggR6{$1ZeNyf8w7QlHUP2lH3sk(ec>K)BP;9;B5H*3}R+vHj?Gi=bq)m-svhQW` z_FS})1t@AJF&|Nneq zIv~&`3frc!!PU6ra@=&yQB}#`$FYV3>SpuE=3l!x$0v;G`Ks zw=)HwP3owO=kXQyxT&_QCs5YsiduGS6&MpTIsb`B3h!$)OTZH`ovjtA0+OKdZ?+X>3H7s+4J70 zQySuHSvli2&)L9x#%%h82PZA9{qN|^zP6%e-$8RGi<;Obqc}|oA*?^C&%n#As9Hb_8R^z&~sd8@JxzDd2#3)r(=q-H2VEZ|3 z<@@*$CezbY%&Zc|~Xe8P^5HXO!n3-D6p7eXcC~fZ(nvy5h+uvz{(mTeMzyUE<88H>PZi zSg9NTc#>4r>0@_~Y)ZYt`r65URkBX#=G0Rg&Mvz@t-)|xzRSE*UHc}ByXJqMwl*L< z`q9%}sRF(F(W_IZf1awP+P_74_mthKPu5O+BJJbj%GX@u)WB}*B)KleNv&FK|F=E& zXP#VZE59Y3SIAWI$v=Z~wUl)Y2Tw>XIZ?bL?V5spqfn<^<7_kk{$I>i^A1~IejMHW z?RBzsP|IVzXKaBQ91A8#lnJyu6m@7U`cmRlb+*_0=xwcg3mkWKUwCeZEpVyNdiv>uK}3JY>((`u=T=no+m&?$AHN^)*5JNtUE4pQ zxpS<3vbL%>`d~icVFLo zSLxKtWecICG_SQf?TUURTBLYg1$Jvs_SBQFe^56V^`O@*KZxd!YFH!UI z>YFe{@LFkK>CzuMX$3syKc942@OAq?k~{gUO?_YLe{Qv!fIsUWOlLc0R(SgRlLr(64JS(fcS55X?wRcPBq}quqWNJT(Si736 zTw9#JJ;vr~%%6E?fsZqO*xmWG%4SWA{3lH}=ZB_W_;xeDWB;&bf%yWKJCX}$T05V; z!Pzq(+L>py0(ifbwR?>_o@ zyDazahl-YE>o++6;;wrinK^lfvhIQS$srd5C;wM8)d@QkRMECCQFXxw-SzspyIyu| zdOq)=?(ClpXKSp#)Sh7pnX%dHmc8;4t9li&ho&?B@>RcoH#@as`#(nJJDl70zCOF< zb)h%w*=f(Yx4oM_``x^4m;3*5gUV(mxild!Rt5%sPJCsvD)zG3zqACiaQ2rD7qIQV zE}ewGQkPT`m@F85&bU9CVzO{$#2KMEO}RH;Z~GGOQu{J^N!Y}S zJ`tWQZMn}E=7%iYmVWK@^j59Y<2Eis=JjfD zJn4#Fx+!#}Mn`Jb)9IbP3y)0Ho>bg{t5TBn$qm6TK0zF<}W$zei)`tePgrvdvaJ~nyA** zO`+@$_Eto#+n$zd{Qd5n$fEqpdX49~cFyjW{vy}rU5nlK_-f4p6WjoI%xlTGEw)*KD)2ZTb_@>ob{b$tla^`0fb@}hE#cP!$rKh~=A=kRB zj>Z0m8+7h&`YRDDm6s6kNG|JzyVEo~dn2i52JeqIwYl0{Dv+I@Eu(TNHg`$3NAJmb z%Xc(&yTAK#Xyd*&vrZ_yDu}x^r^9#i2P4DuTZ>MF%~QNram$i#u1xxN?QO1S(l*DK zZ7)80X&ckw+^xbJHvBqu>ZbC`;+QLQj=EcHY2c6Dam1dzb+_6+?nJ@vvWO|g^RAq= zTpV_8^X;4L70cQ8-l;!ycl(DA>=MW1L>}{-*xqhV7hiR8KX?9(=_X(7nRkDX{w2rc zwxg2&V0lkiL2owyMhBm%XWpi~R5+|!wO(NF^cS@~zorOkJ+@btkM{76h%ZoIQ+x5k zt$dE6*qe<~U-MLYzi0ep@Reh?>VNe|_x&8Eb(X0sC+X>JxO?|a-W=z|3&Jh8tk%gW zt@+_`D6oJ#rX_rz=nK^)2Y&I_rCOS9>B_ZP{CVfDP29S_et9aNR7fdu+HrDLo2(H3 zlnXN_S;Xp{KmTN+xA8A&pQ}%+__xMS_p&kF(tGsF_7^54vxP1_fBXG~>6Z5oHVF#% zzuPtUgM`1|B*O^lg4r+1Z#>(b^Nd5<#;bF34f8w0t%X(U24~;TQn}f)%=u2hzh`si z_?140n51ek-=Bvg(d5e4%de%JO07#y@y)rBH0R6S$xE9`q|#>i%$l)z%EO16W|Dxcc_Xp0Y z{G?a#PfYWaa@emKO(}+L>n9{_HLf`IW?$LyBhAh#EBngS;_JNb)U+=-ZNz*mFsph; z#)r8V{6sQ}mzB?yxL+U;KgUtZ%5B%VxeA%@c2s7+$T$-5&{kMC!nXNiYw-QE|G|SL zFQwiv39&FRu(N{-8Ac`%1`(8TAK0J{Xxs-nz5}IDMu7snQMDqE!H7ULKqy-rV?f9z zfExP9T>#Kn4MaDHJc*^m!x*_iHx9X>3+gw341(YuHrxY2uwDeZX~;!0sBsK22}FKn u$21LFQyJYv + + org.h2.compress + h2-lzf + 1.0 + + + 1.0 + + 20091122093116 + + From 26f97f4d46d35fa86da3304a3b5e29216d1eaba2 Mon Sep 17 00:00:00 2001 From: jboner Date: Sun, 22 Nov 2009 15:25:16 +0100 Subject: [PATCH 09/20] cleaned up logging and error reporting --- .../src/main/scala/actor/ActiveObject.scala | 3 +- akka-actors/src/main/scala/actor/Actor.scala | 89 ++++++- .../src/main/scala/nio/RemoteClient.scala | 6 +- .../src/main/scala/nio/RemoteServer.scala | 28 +-- .../src/main/scala/CassandraStorage.scala | 237 +----------------- akka-security/src/main/scala/Security.scala | 2 +- 6 files changed, 101 insertions(+), 264 deletions(-) diff --git a/akka-actors/src/main/scala/actor/ActiveObject.scala b/akka-actors/src/main/scala/actor/ActiveObject.scala index 566e2a9f41..3395b6ac59 100644 --- a/akka-actors/src/main/scala/actor/ActiveObject.scala +++ b/akka-actors/src/main/scala/actor/ActiveObject.scala @@ -10,12 +10,13 @@ import se.scalablesolutions.akka.dispatch.{MessageDispatcher, FutureResult} import se.scalablesolutions.akka.nio.protobuf.RemoteProtocol.RemoteRequest import se.scalablesolutions.akka.nio.{RemoteProtocolBuilder, RemoteClient, RemoteRequestIdFactory} import se.scalablesolutions.akka.config.ScalaConfig._ +import se.scalablesolutions.akka.serialization.Serializer import se.scalablesolutions.akka.util._ import org.codehaus.aspectwerkz.joinpoint.{MethodRtti, JoinPoint} import org.codehaus.aspectwerkz.proxy.Proxy import org.codehaus.aspectwerkz.annotation.{Aspect, Around} -import se.scalablesolutions.akka.serialization.Serializer + import java.lang.reflect.{InvocationTargetException, Method} object Annotations { diff --git a/akka-actors/src/main/scala/actor/Actor.scala b/akka-actors/src/main/scala/actor/Actor.scala index bc7a8806f3..3616868cbe 100644 --- a/akka-actors/src/main/scala/actor/Actor.scala +++ b/akka-actors/src/main/scala/actor/Actor.scala @@ -25,10 +25,18 @@ import org.multiverse.utils.ThreadLocalTransaction._ /** * Mix in this trait to give an actor TransactionRequired semantics. - * Equivalent to invoking the 'makeTransactionRequired' method in the actor. + * Equivalent to invoking the 'makeTransactionRequired' method in the actor. */ trait TransactionRequired { this: Actor => - makeTransactionRequired + makeTransactionRequired +} + +/** + * Extend this abstract class to create a remote actor. + * Equivalent to invoking the 'makeRemote(..)' method in or on the actor. + */ +abstract class RemoteActor(hostname: String, port: Int) extends Actor { + makeRemote(hostname, port) } @serializable sealed trait LifeCycleMessage @@ -64,22 +72,81 @@ object Actor { implicit val any: AnyRef = this + /** + * Use to create an anonymous event-driven actor. + * The actor is started when created. + * Example: + *

+   * import Actor._
+   *
+   * val a = actor {
+   *   case msg => ... // handle message
+   * }
+   * 
+ */ def actor(body: PartialFunction[Any, Unit]): Actor = new Actor() { start def receive = body } + /** + * Use to create an anonymous event-driven actor with both an init block and a message loop block. + * The actor is started when created. + * Example: + *
+   * import Actor._
+   *
+   * val a = actor {
+   *   ... // init stuff
+   * } {
+   *   case msg => ... // handle message
+   * }
+   * 
+ */ def actor(body: => Unit)(matcher: PartialFunction[Any, Unit]): Actor = new Actor() { start body def receive = matcher } + /** + * Use to create an anonymous event-driven actor with a life-cycle configuration. + * The actor is started when created. + * Example: + *
+   * import Actor._
+   *
+   * val a = actor(LifeCycle(Temporary)) {
+   *   case msg => ... // handle message
+   * }
+   * 
+ */ def actor(lifeCycleConfig: LifeCycle)(body: PartialFunction[Any, Unit]): Actor = new Actor() { lifeCycle = lifeCycleConfig start def receive = body } + + /** + * Use to create an anonymous event-driven actor with both an init block and a message loop block + * as well as a life-cycle configuration. + * The actor is started when created. + * Example: + *
+   * import Actor._
+   *
+   * val a = actor(LifeCycle(Temporary)) {
+   *   ... // init stuff
+   * } {
+   *   case msg => ... // handle message
+   * }
+   * 
+ */ + def actor(lifeCycleConfig: LifeCycle)(body: => Unit)(matcher: PartialFunction[Any, Unit]): Actor = new Actor() { + start + body + def receive = matcher + } } /** @@ -607,7 +674,8 @@ trait Actor extends Logging with TransactionManagement { } } - private def postMessageToMailboxAndCreateFutureResultWithTimeout(message: AnyRef, timeout: Long): CompletableFutureResult = _remoteFlagLock.withReadLock { // the price you pay for being able to make an actor remote at runtime + private def postMessageToMailboxAndCreateFutureResultWithTimeout(message: AnyRef, timeout: Long): + CompletableFutureResult = _remoteFlagLock.withReadLock { // the price you pay for being able to make an actor remote at runtime if (_remoteAddress.isDefined) { val requestBuilder = RemoteRequest.newBuilder .setId(RemoteRequestIdFactory.nextId) @@ -636,8 +704,14 @@ trait Actor extends Logging with TransactionManagement { * Callback for the dispatcher. E.g. single entry point to the user code and all protected[this] methods */ private[akka] def invoke(messageHandle: MessageInvocation) = synchronized { - if (TransactionManagement.isTransactionalityEnabled) transactionalDispatch(messageHandle) - else dispatch(messageHandle) + try { + if (TransactionManagement.isTransactionalityEnabled) transactionalDispatch(messageHandle) + else dispatch(messageHandle) + } catch { + case e => + log.error(e, e.getMessage) // for logging the exception to log file + throw e + } } private def dispatch[T](messageHandle: MessageInvocation) = { @@ -652,10 +726,10 @@ trait Actor extends Logging with TransactionManagement { else throw new IllegalArgumentException("No handler matching message [" + message + "] in " + toString) } catch { case e => + log.error(e, e.getMessage) // FIXME to fix supervisor restart of remote actor for oneway calls, inject a supervisor proxy that can send notification back to client if (_supervisor.isDefined) _supervisor.get ! Exit(this, e) if (senderFuture.isDefined) senderFuture.get.completeWithException(this, e) - else e.printStackTrace } finally { clearTransaction } @@ -692,9 +766,8 @@ trait Actor extends Logging with TransactionManagement { } else proceed } catch { case e => - e.printStackTrace + log.error(e, e.getMessage) if (senderFuture.isDefined) senderFuture.get.completeWithException(this, e) - else e.printStackTrace clearTransaction // need to clear currentTransaction before call to supervisor // FIXME to fix supervisor restart of remote actor for oneway calls, inject a supervisor proxy that can send notification back to client if (_supervisor.isDefined) _supervisor.get ! Exit(this, e) diff --git a/akka-actors/src/main/scala/nio/RemoteClient.scala b/akka-actors/src/main/scala/nio/RemoteClient.scala index 99872beb33..7851286902 100644 --- a/akka-actors/src/main/scala/nio/RemoteClient.scala +++ b/akka-actors/src/main/scala/nio/RemoteClient.scala @@ -80,8 +80,7 @@ class RemoteClient(hostname: String, port: Int) extends Logging { // Wait until the connection attempt succeeds or fails. connection.awaitUninterruptibly if (!connection.isSuccess) { - log.error("Remote connection to [%s:%s] has failed due to [%s]", hostname, port, connection.getCause) - connection.getCause.printStackTrace + log.error(connection.getCause, "Remote connection to [%s:%s] has failed", hostname, port) } isRunning = true } @@ -212,8 +211,7 @@ class RemoteClientHandler(val name: String, log.debug("Remote client disconnected from [%s]", ctx.getChannel.getRemoteAddress); override def exceptionCaught(ctx: ChannelHandlerContext, event: ExceptionEvent) = { - log.error("Unexpected exception from downstream in remote client: %s", event.getCause) - event.getCause.printStackTrace + log.error(event.getCause, "Unexpected exception from downstream in remote client") event.getChannel.close } diff --git a/akka-actors/src/main/scala/nio/RemoteServer.scala b/akka-actors/src/main/scala/nio/RemoteServer.scala index c9528dc6a4..ba3338f39a 100755 --- a/akka-actors/src/main/scala/nio/RemoteServer.scala +++ b/akka-actors/src/main/scala/nio/RemoteServer.scala @@ -105,6 +105,8 @@ class RemoteServerPipelineFactory(name: String, loader: Option[ClassLoader]) @ChannelPipelineCoverage { val value = "all" } class RemoteServerHandler(val name: String, val applicationLoader: Option[ClassLoader]) extends SimpleChannelUpstreamHandler with Logging { + val AW_PROXY_PREFIX = "$$ProxiedByAW".intern + private val activeObjects = new ConcurrentHashMap[String, AnyRef] private val actors = new ConcurrentHashMap[String, Actor] @@ -126,8 +128,7 @@ class RemoteServerHandler(val name: String, val applicationLoader: Option[ClassL } override def exceptionCaught(ctx: ChannelHandlerContext, event: ExceptionEvent) = { - log.error("Unexpected exception from remote downstream: %s", event.getCause) - event.getCause.printStackTrace + log.error(event.getCause, "Unexpected exception from remote downstream") event.getChannel.close } @@ -159,8 +160,7 @@ class RemoteServerHandler(val name: String, val applicationLoader: Option[ClassL channel.write(replyMessage) } catch { case e: Throwable => - log.error("Could not invoke remote actor [%s] due to: %s", request.getTarget, e) - e.printStackTrace + log.error(e, "Could not invoke remote actor [%s]", request.getTarget) val replyBuilder = RemoteReply.newBuilder .setId(request.getId) .setException(e.getClass.getName + "$" + e.getMessage) @@ -200,10 +200,7 @@ class RemoteServerHandler(val name: String, val applicationLoader: Option[ClassL } } catch { case e: InvocationTargetException => - log.error( - "Could not invoke remote active object [%s :: %s] due to: %s", - request.getMethod, request.getTarget, e.getCause) - e.getCause.printStackTrace + log.error(e.getCause, "Could not invoke remote active object [%s :: %s]", request.getMethod, request.getTarget) val replyBuilder = RemoteReply.newBuilder .setId(request.getId) .setException(e.getCause.getClass.getName + "$" + e.getCause.getMessage) @@ -213,10 +210,7 @@ class RemoteServerHandler(val name: String, val applicationLoader: Option[ClassL val replyMessage = replyBuilder.build channel.write(replyMessage) case e: Throwable => - log.error( - "Could not invoke remote active object [%s :: %s] due to: %s", - request.getMethod, request.getTarget, e) - e.printStackTrace + log.error(e.getCause, "Could not invoke remote active object [%s :: %s]", request.getMethod, request.getTarget) val replyBuilder = RemoteReply.newBuilder .setId(request.getId) .setException(e.getClass.getName + "$" + e.getMessage) @@ -247,9 +241,9 @@ class RemoteServerHandler(val name: String, val applicationLoader: Option[ClassL val escapedArgs = for (i <- 0 until args.size) { val arg = args(i) - if (arg.isInstanceOf[String] && arg.asInstanceOf[String].startsWith("$$ProxiedByAW")) { + if (arg.isInstanceOf[String] && arg.asInstanceOf[String].startsWith(AW_PROXY_PREFIX)) { val argString = arg.asInstanceOf[String] - val proxyName = argString.replace("$$ProxiedByAW", "") //argString.substring(argString.indexOf("$$ProxiedByAW"), argString.length) + val proxyName = argString.replace(AW_PROXY_PREFIX, "") //argString.substring(argString.indexOf("$$ProxiedByAW"), argString.length) val activeObject = createActiveObject(proxyName, timeout) unescapedArgs(i) = activeObject unescapedArgClasses(i) = Class.forName(proxyName) @@ -273,8 +267,7 @@ class RemoteServerHandler(val name: String, val applicationLoader: Option[ClassL newInstance } catch { case e => - log.debug("Could not create remote active object instance due to: %s", e) - e.printStackTrace + log.error(e, "Could not create remote active object instance") throw e } } else activeObjectOrNull @@ -295,8 +288,7 @@ class RemoteServerHandler(val name: String, val applicationLoader: Option[ClassL newInstance } catch { case e => - log.error(e, "Could not create remote actor instance due to: " + e.getMessage) - e.printStackTrace + log.error(e, "Could not create remote actor object instance") throw e } } else actorOrNull diff --git a/akka-persistence/src/main/scala/CassandraStorage.scala b/akka-persistence/src/main/scala/CassandraStorage.scala index 0769053909..74f06d3a9d 100644 --- a/akka-persistence/src/main/scala/CassandraStorage.scala +++ b/akka-persistence/src/main/scala/CassandraStorage.scala @@ -10,8 +10,6 @@ import se.scalablesolutions.akka.serialization.Serializer import se.scalablesolutions.akka.Config.config import org.apache.cassandra.service._ -import org.apache.thrift.transport._ -import org.apache.thrift.protocol._ /** * @author Jonas Bonér @@ -92,7 +90,7 @@ object CassandraStorage extends MapStorage else None } catch { case e => - e.printStackTrace + log.error(e, "Could not retreive Ref from storage") None } } @@ -111,7 +109,7 @@ object CassandraStorage extends MapStorage } } - // FIXME implement + // FIXME implement insertVectorStorageEntriesFor def insertVectorStorageEntriesFor(name: String, elements: List[AnyRef]) = { throw new UnsupportedOperationException("insertVectorStorageEntriesFor for CassandraStorage is not implemented yet") } @@ -189,7 +187,7 @@ object CassandraStorage extends MapStorage else None } catch { case e => - e.printStackTrace + log.error(e, "Could not retreive Map from storage") None } } @@ -205,11 +203,8 @@ object CassandraStorage extends MapStorage } } - - def getMapStorageSizeFor(name: String): Int = { - sessions.withSession { - _ |# (name, MAP_COLUMN_PARENT) - } + def getMapStorageSizeFor(name: String): Int = sessions.withSession { + _ |# (name, MAP_COLUMN_PARENT) } def removeMapStorageFor(name: String): Unit = removeMapStorageFor(name, null) @@ -234,225 +229,3 @@ object CassandraStorage extends MapStorage columns.map(column => (column.getColumn.name, serializer.in(column.getColumn.value, None))) } } - -/** - * NOTE: requires command line options: - *
- * -Dcassandra -Dstorage-config=config/ -Dpidfile=akka.pid - *

- * @author Jonas Bonér - * -object EmbeddedCassandraStorage extends Logging { -val KEYSPACE = "akka" -val MAP_COLUMN_FAMILY = "map" -val VECTOR_COLUMN_FAMILY = "vector" -val REF_COLUMN_FAMILY = "ref:item" - -val IS_ASCENDING = true - -val RUN_THRIFT_SERVICE = akka.akka.config.getBool("akka.storage.cassandra.thrift-server.service", false) -val CONSISTENCY_LEVEL = { -if (akka.akka.config.getBool("akka.storage.cassandra.blocking", true)) 0 -else 1 } - -@volatile private[this] var isRunning = false -private[this] val serializer: Serializer = { -akka.akka.config.getString("akka.storage.cassandra.storage-format", "java") match { -case "scala-json" => Serializer.ScalaJSON -case "java-json" => Serializer.JavaJSON -case "protobuf" => Serializer.Protobuf -case "java" => Serializer.Java -case "sbinary" => throw new UnsupportedOperationException("SBinary serialization protocol is not yet supported for storage") -case "avro" => throw new UnsupportedOperationException("Avro serialization protocol is not yet supported for storage") -case unknown => throw new UnsupportedOperationException("Unknown storage serialization protocol [" + unknown + "]") -} -} - -// TODO: is this server thread-safe or needed to be wrapped up in an actor? -private[this] val server = classOf[CassandraServer].newInstance.asInstanceOf[CassandraServer] - -private[this] var thriftServer: CassandraThriftServer = _ - -def start = synchronized { -if (!isRunning) { -try { -server.start -log.info("Cassandra persistent storage has started up successfully"); -} catch { -case e => -log.error("Could not start up Cassandra persistent storage") -throw e -} -if (RUN_THRIFT_SERVICE) { -thriftServer = new CassandraThriftServer(server) -thriftServer.start -} -isRunning -} -} - -def stop = if (isRunning) { -//server.storageService.shutdown -if (RUN_THRIFT_SERVICE) thriftServer.stop -} - -// =============================================================== -// For Ref -// =============================================================== - -def insertRefStorageFor(name: String, element: AnyRef) = { -server.insert( -KEYSPACE, -name, -REF_COLUMN_FAMILY, -element, -System.currentTimeMillis, -CONSISTENCY_LEVEL) -} - -def getRefStorageFor(name: String): Option[AnyRef] = { -try { -val column = server.get_column(KEYSPACE, name, REF_COLUMN_FAMILY) -Some(serializer.in(column.value, None)) -} catch { -case e => -e.printStackTrace -None } -} - -// =============================================================== -// For Vector -// =============================================================== - -def insertVectorStorageEntryFor(name: String, element: AnyRef) = { -server.insert( -KEYSPACE, -name, -VECTOR_COLUMN_FAMILY + ":" + getVectorStorageSizeFor(name), -element, -System.currentTimeMillis, -CONSISTENCY_LEVEL) -} - -def getVectorStorageEntryFor(name: String, index: Int): AnyRef = { -try { -val column = server.get_column(KEYSPACE, name, VECTOR_COLUMN_FAMILY + ":" + index) -serializer.in(column.value, None) -} catch { -case e => -e.printStackTrace -throw new Predef.NoSuchElementException(e.getMessage) -} -} - -def getVectorStorageRangeFor(name: String, start: Int, count: Int): List[AnyRef] = -server.get_slice(KEYSPACE, name, VECTOR_COLUMN_FAMILY, IS_ASCENDING, count) -.toArray.toList.asInstanceOf[List[Tuple2[String, AnyRef]]].map(tuple => tuple._2) - -def getVectorStorageSizeFor(name: String): Int = -server.get_column_count(KEYSPACE, name, VECTOR_COLUMN_FAMILY) - -// =============================================================== -// For Map -// =============================================================== - -def insertMapStorageEntryFor(name: String, key: String, value: AnyRef) = { -server.insert( -KEYSPACE, name, -MAP_COLUMN_FAMILY + ":" + key, -serializer.out(value), -System.currentTimeMillis, -CONSISTENCY_LEVEL) -} - -def insertMapStorageEntriesFor(name: String, entries: List[Tuple2[String, AnyRef]]) = { -import java.util.{ Map, HashMap, List, ArrayList } -val columns: Map[String, List[column_t]] = new HashMap -for (entry <- entries) { -val cls: List[column_t] = new ArrayList -cls.add(new column_t(entry._1, serializer.out(entry._2), System.currentTimeMillis)) -columns.put(MAP_COLUMN_FAMILY, cls) -} -server.batch_insert(new BatchMutation( -KEYSPACE, name, -columns), -CONSISTENCY_LEVEL) -} - -def getMapStorageEntryFor(name: String, key: AnyRef): Option[AnyRef] = { -try { -val column = server.get_column(KEYSPACE, name, MAP_COLUMN_FAMILY + ":" + key) -Some(serializer.in(column.value, None)) -} catch { -case e => -e.printStackTrace -None -} -} - -def getMapStorageFor(name: String): List[Tuple2[String, AnyRef]] = { -val columns = server.get_columns_since(KEYSPACE, name, MAP_COLUMN_FAMILY, -1) -.toArray.toList.asInstanceOf[List[org.apache.cassandra.service.column_t]] -for { -column <- columns -col = (column.columnName, serializer.in(column.value, None)) -} yield col -} - -def getMapStorageSizeFor(name: String): Int = -server.get_column_count(KEYSPACE, name, MAP_COLUMN_FAMILY) - -def removeMapStorageFor(name: String) = -server.remove(KEYSPACE, name, MAP_COLUMN_FAMILY, System.currentTimeMillis, CONSISTENCY_LEVEL) - -def getMapStorageRangeFor(name: String, start: Int, count: Int): List[Tuple2[String, AnyRef]] = { -server.get_slice(KEYSPACE, name, MAP_COLUMN_FAMILY, IS_ASCENDING, count) -.toArray.toList.asInstanceOf[List[Tuple2[String, AnyRef]]] -} -} - - -class CassandraThriftServer(server: CassandraServer) extends Logging { -case object Start -case object Stop - -private[this] val serverEngine: TThreadPoolServer = try { -val pidFile = akka.akka.config.getString("akka.storage.cassandra.thrift-server.pidfile", "akka.pid") -if (pidFile != null) new File(pidFile).deleteOnExit(); -val listenPort = DatabaseDescriptor.getThriftPort - -val processor = new Cassandra.Processor(server) -val tServerSocket = new TServerSocket(listenPort) -val tProtocolFactory = new TBinaryProtocol.Factory - -val options = new TThreadPoolServer.Options -options.minWorkerThreads = 64 -new TThreadPoolServer(new TProcessorFactory(processor), -tServerSocket, -new TTransportFactory, -new TTransportFactory, -tProtocolFactory, -tProtocolFactory, -options) -} catch { -case e => -log.error("Could not start up Cassandra thrift service") -throw e -} - -import scala.actors.Actor._ -private[this] val serverDaemon = actor { -receive { -case Start => -serverEngine.serve -log.info("Cassandra thrift service has starting up successfully") -case Stop => -log.info("Cassandra thrift service is shutting down...") -serverEngine.stop -} -} - -def start = serverDaemon ! Start -def stop = serverDaemon ! Stop -} - */ diff --git a/akka-security/src/main/scala/Security.scala b/akka-security/src/main/scala/Security.scala index 384af1ea20..6efa5bdcce 100644 --- a/akka-security/src/main/scala/Security.scala +++ b/akka-security/src/main/scala/Security.scala @@ -367,7 +367,7 @@ trait SpnegoAuthenticationActor extends AuthenticationActor[SpnegoCredentials] { Some(UserInfo(user, null, rolesFor(user))) } catch { case e: PrivilegedActionException => { - e.printStackTrace + log.error(e, "Action not allowed") return None } } From 8f55ec6c641379faf1b4dd324a7d753f7258baef Mon Sep 17 00:00:00 2001 From: jboner Date: Mon, 23 Nov 2009 15:19:53 +0100 Subject: [PATCH 10/20] Fixed problem with implicit sender + updated changes.xml --- .../src/main/scala/actor/ActiveObject.scala | 2 +- akka-actors/src/main/scala/actor/Actor.scala | 39 +- .../src/main/scala/nio/RemoteClient.scala | 2 +- .../src/main/scala/nio/RemoteServer.scala | 5 +- .../ActorFireForgetRequestReplyTest.scala | 10 +- .../EventBasedSingleThreadActorTest.scala | 3 +- .../scala/EventBasedThreadPoolActorTest.scala | 3 +- .../src/test/scala/RemoteActorTest.scala | 3 +- .../src/test/scala/RemoteSupervisorTest.scala | 3 +- .../src/test/scala/SupervisorTest.scala | 3 +- .../src/test/scala/ThreadBasedActorTest.scala | 3 +- akka-amqp/src/main/scala/AMQP.scala | 419 ++++++++++-------- akka-amqp/src/main/scala/ExampleSession.scala | 1 + akka-persistence/src/test/scala/AllTest.scala | 2 +- changes.xml | 35 +- 15 files changed, 322 insertions(+), 211 deletions(-) diff --git a/akka-actors/src/main/scala/actor/ActiveObject.scala b/akka-actors/src/main/scala/actor/ActiveObject.scala index 3395b6ac59..f6b45bcf53 100644 --- a/akka-actors/src/main/scala/actor/ActiveObject.scala +++ b/akka-actors/src/main/scala/actor/ActiveObject.scala @@ -161,7 +161,6 @@ private[akka] sealed case class AspectInit( */ @Aspect("perInstance") private[akka] sealed class ActiveObjectAspect { - import Actor._ @volatile var isInitialized = false var target: Class[_] = _ @@ -188,6 +187,7 @@ private[akka] sealed class ActiveObjectAspect { } private def localDispatch(joinPoint: JoinPoint): AnyRef = { + import Actor.Sender.Self val rtti = joinPoint.getRtti.asInstanceOf[MethodRtti] if (isOneWay(rtti)) actor ! Invocation(joinPoint, true, true) else { diff --git a/akka-actors/src/main/scala/actor/Actor.scala b/akka-actors/src/main/scala/actor/Actor.scala index 3616868cbe..ea2c64d880 100644 --- a/akka-actors/src/main/scala/actor/Actor.scala +++ b/akka-actors/src/main/scala/actor/Actor.scala @@ -70,7 +70,18 @@ object Actor { val TIMEOUT = config.getInt("akka.actor.timeout", 5000) val SERIALIZE_MESSAGES = config.getBool("akka.actor.serialize-messages", false) - implicit val any: AnyRef = this + object Sender extends Actor { + implicit val Self: AnyRef = this + def receive = { + case unknown => + log.error( + "Actor.Sender can't process messages. Received message [%s]." + + "This error could occur if you either:" + + "\n\t- Explicitly send a message to the Actor.Sender object." + + "\n\t- Invoking the 'reply(..)' method or sending a message to the 'sender' reference " + + "\n\t when you have sent the original request from a instance *not* being an actor.", unknown) + } + } /** * Use to create an anonymous event-driven actor. @@ -165,7 +176,7 @@ object Actor { trait Actor extends Logging with TransactionManagement { ActorRegistry.register(this) - implicit val self: AnyRef = this + implicit protected val self: Actor = this // FIXME http://www.assembla.com/spaces/akka/tickets/56-Change-UUID-generation-for-the-TransactionManagement-trait private[akka] var _uuid = Uuid.newUuid.toString @@ -398,12 +409,30 @@ trait Actor extends Logging with TransactionManagement { /** * Sends a one-way asynchronous message. E.g. fire-and-forget semantics. *

+ * * If invoked from within an actor then the actor reference is implicitly passed on as the implicit 'sender' argument. + *

+ * * This actor 'sender' reference is then available in the receiving actor in the 'sender' member variable. - *

- * If invoked from within another object then add this import to resolve the implicit argument: *

-   * import se.scalablesolutions.akka.actor.Actor._
+   *   actor ! message
+   * 
+ *

+ * + * If invoked from within a *non* Actor instance then either add this import to resolve the implicit argument: + *

+   *   import Actor.Sender._
+   *   actor ! message
+   * 
+ * + * Or pass in the implicit argument explicitly: + *
+   *   actor.!(message)(this)
+   * 
+ * + * Or use the 'send(..)' method; + *
+   *   actor.send(message)
    * 
*/ def !(message: AnyRef)(implicit sender: AnyRef) = { diff --git a/akka-actors/src/main/scala/nio/RemoteClient.scala b/akka-actors/src/main/scala/nio/RemoteClient.scala index 7851286902..658e400a65 100644 --- a/akka-actors/src/main/scala/nio/RemoteClient.scala +++ b/akka-actors/src/main/scala/nio/RemoteClient.scala @@ -156,6 +156,7 @@ class RemoteClientHandler(val name: String, val supervisors: ConcurrentMap[String, Actor], val bootstrap: ClientBootstrap) extends SimpleChannelUpstreamHandler with Logging { + import Actor.Sender.Self override def handleUpstream(ctx: ChannelHandlerContext, event: ChannelEvent) = { if (event.isInstanceOf[ChannelStateEvent] && @@ -166,7 +167,6 @@ class RemoteClientHandler(val name: String, } override def messageReceived(ctx: ChannelHandlerContext, event: MessageEvent) { - import Actor._ try { val result = event.getMessage if (result.isInstanceOf[RemoteReply]) { diff --git a/akka-actors/src/main/scala/nio/RemoteServer.scala b/akka-actors/src/main/scala/nio/RemoteServer.scala index ba3338f39a..fd770bc6f5 100755 --- a/akka-actors/src/main/scala/nio/RemoteServer.scala +++ b/akka-actors/src/main/scala/nio/RemoteServer.scala @@ -139,12 +139,13 @@ class RemoteServerHandler(val name: String, val applicationLoader: Option[ClassL } private def dispatchToActor(request: RemoteRequest, channel: Channel) = { - import Actor._ log.debug("Dispatching to remote actor [%s]", request.getTarget) val actor = createActor(request.getTarget, request.getUuid, request.getTimeout) actor.start val message = RemoteProtocolBuilder.getMessage(request) - if (request.getIsOneWay) actor ! message + if (request.getIsOneWay) { + actor.send(message) + } else { try { val resultOrNone = actor !! message diff --git a/akka-actors/src/test/scala/ActorFireForgetRequestReplyTest.scala b/akka-actors/src/test/scala/ActorFireForgetRequestReplyTest.scala index 826f157593..2804e588d8 100644 --- a/akka-actors/src/test/scala/ActorFireForgetRequestReplyTest.scala +++ b/akka-actors/src/test/scala/ActorFireForgetRequestReplyTest.scala @@ -27,25 +27,27 @@ class ActorFireForgetRequestReplyTest extends JUnitSuite { @Test def shouldReplyToBangMessageUsingReply = { - import Actor._ + import Actor.Sender.Self + val replyActor = new ReplyActor replyActor.start val senderActor = new SenderActor(replyActor) senderActor.start senderActor ! "Init" - Thread.sleep(10000) + Thread.sleep(1000) assert("Reply" === state.s) } @Test def shouldReplyToBangMessageUsingImplicitSender = { - import Actor._ + import Actor.Sender.Self + val replyActor = new ReplyActor replyActor.start val senderActor = new SenderActor(replyActor) senderActor.start senderActor ! "InitImplicit" - Thread.sleep(10000) + Thread.sleep(1000) assert("ReplyImplicit" === state.s) } } diff --git a/akka-actors/src/test/scala/EventBasedSingleThreadActorTest.scala b/akka-actors/src/test/scala/EventBasedSingleThreadActorTest.scala index 46661e3b97..e556a1a724 100644 --- a/akka-actors/src/test/scala/EventBasedSingleThreadActorTest.scala +++ b/akka-actors/src/test/scala/EventBasedSingleThreadActorTest.scala @@ -8,7 +8,8 @@ import org.junit.Test import se.scalablesolutions.akka.dispatch.Dispatchers class EventBasedSingleThreadActorTest extends JUnitSuite { - import Actor._ + import Actor.Sender.Self + private val unit = TimeUnit.MILLISECONDS class TestActor extends Actor { diff --git a/akka-actors/src/test/scala/EventBasedThreadPoolActorTest.scala b/akka-actors/src/test/scala/EventBasedThreadPoolActorTest.scala index 2030942b7a..2d90145810 100644 --- a/akka-actors/src/test/scala/EventBasedThreadPoolActorTest.scala +++ b/akka-actors/src/test/scala/EventBasedThreadPoolActorTest.scala @@ -6,7 +6,8 @@ import org.scalatest.junit.JUnitSuite import org.junit.Test class EventBasedThreadPoolActorTest extends JUnitSuite { - import Actor._ + import Actor.Sender.Self + private val unit = TimeUnit.MILLISECONDS class TestActor extends Actor { diff --git a/akka-actors/src/test/scala/RemoteActorTest.scala b/akka-actors/src/test/scala/RemoteActorTest.scala index 191898269b..884a0d007f 100644 --- a/akka-actors/src/test/scala/RemoteActorTest.scala +++ b/akka-actors/src/test/scala/RemoteActorTest.scala @@ -27,7 +27,8 @@ class RemoteActorSpecActorBidirectional extends Actor { } class RemoteActorTest extends JUnitSuite { - import Actor._ + import Actor.Sender.Self + akka.Config.config new Thread(new Runnable() { def run = { diff --git a/akka-actors/src/test/scala/RemoteSupervisorTest.scala b/akka-actors/src/test/scala/RemoteSupervisorTest.scala index 9405af6dc9..ac6f1777ab 100644 --- a/akka-actors/src/test/scala/RemoteSupervisorTest.scala +++ b/akka-actors/src/test/scala/RemoteSupervisorTest.scala @@ -20,7 +20,8 @@ object Log { * @author Jonas Bonér */ class RemoteSupervisorTest extends JUnitSuite { - import Actor._ + import Actor.Sender.Self + akka.Config.config new Thread(new Runnable() { def run = { diff --git a/akka-actors/src/test/scala/SupervisorTest.scala b/akka-actors/src/test/scala/SupervisorTest.scala index df59ee832c..b143ef21e7 100644 --- a/akka-actors/src/test/scala/SupervisorTest.scala +++ b/akka-actors/src/test/scala/SupervisorTest.scala @@ -13,7 +13,8 @@ import org.junit.Test * @author Jonas Bonér */ class SupervisorTest extends JUnitSuite { - import Actor._ + import Actor.Sender.Self + var messageLog: String = "" var oneWayLog: String = "" diff --git a/akka-actors/src/test/scala/ThreadBasedActorTest.scala b/akka-actors/src/test/scala/ThreadBasedActorTest.scala index 335a6f461b..ead74068d1 100644 --- a/akka-actors/src/test/scala/ThreadBasedActorTest.scala +++ b/akka-actors/src/test/scala/ThreadBasedActorTest.scala @@ -8,7 +8,8 @@ import org.junit.Test import se.scalablesolutions.akka.dispatch.Dispatchers class ThreadBasedActorTest extends JUnitSuite { - import Actor._ + import Actor.Sender.Self + private val unit = TimeUnit.MILLISECONDS class TestActor extends Actor { diff --git a/akka-amqp/src/main/scala/AMQP.scala b/akka-amqp/src/main/scala/AMQP.scala index 9f591f9891..af56bfc8a1 100644 --- a/akka-amqp/src/main/scala/AMQP.scala +++ b/akka-amqp/src/main/scala/AMQP.scala @@ -31,10 +31,8 @@ import java.io.IOException * val consumer = AMQP.newConsumer(params, hostname, port, exchange, ExchangeType.Direct, Serializer.ScalaJSON, None, 100) * - * consumer ! MessageConsumerListener(queue, routingKey, new Actor() { - * def receive = { - * case Message(payload, _, _, _, _) => log.debug("Received message: %s", payload) - * } + * consumer ! MessageConsumerListener(queue, routingKey, actor { + * case Message(payload, _, _, _, _) => log.debug("Received message: %s", payload) * }) * * val producer = AMQP.newProducer(params, hostname, port, exchange, Serializer.ScalaJSON, None, None, 100) @@ -43,15 +41,113 @@ import java.io.IOException * * @author Jonas Bonér */ -object AMQP extends Actor { - private val connections = new ConcurrentHashMap[FaultTolerantConnectionActor, FaultTolerantConnectionActor] - faultHandler = Some(OneForOneStrategy(5, 5000)) - trapExit = List(classOf[Throwable]) - start +object AMQP { + private val supervisor = new AMQPSupervisor + + def newProducer( + config: ConnectionParameters, + hostname: String, + port: Int, + exchangeName: String, + returnListener: Option[ReturnListener], + shutdownListener: Option[ShutdownListener], + initReconnectDelay: Long) = + supervisor.newProducer( + config, hostname, port, exchangeName, returnListener, shutdownListener, initReconnectDelay) + + def newConsumer( + config: ConnectionParameters, + hostname: String, + port: Int, + exchangeName: String, + exchangeType: ExchangeType, + shutdownListener: Option[ShutdownListener], + initReconnectDelay: Long, + passive: Boolean, + durable: Boolean, + configurationArguments: Map[String, AnyRef]) = + supervisor.newConsumer( + config, hostname, port, exchangeName, exchangeType, + shutdownListener, initReconnectDelay, passive, durable, configurationArguments) + + def stopConnection(connection: FaultTolerantConnectionActor) = supervisor.stopConnection(connection) + + /** + * @author Jonas Bonér + */ + class AMQPSupervisor extends Actor { + private val connections = new ConcurrentHashMap[FaultTolerantConnectionActor, FaultTolerantConnectionActor] + + faultHandler = Some(OneForOneStrategy(5, 5000)) + trapExit = List(classOf[Throwable]) + start + + def newProducer( + config: ConnectionParameters, + hostname: String, + port: Int, + exchangeName: String, + returnListener: Option[ReturnListener], + shutdownListener: Option[ShutdownListener], + initReconnectDelay: Long): Producer = { + val producer = new Producer( + new ConnectionFactory(config), + hostname, port, + exchangeName, + returnListener, + shutdownListener, + initReconnectDelay) + startLink(producer) + producer + } + + def newConsumer( + config: ConnectionParameters, + hostname: String, + port: Int, + exchangeName: String, + exchangeType: ExchangeType, + shutdownListener: Option[ShutdownListener], + initReconnectDelay: Long, + passive: Boolean, + durable: Boolean, + configurationArguments: Map[String, AnyRef]): Consumer = { + val consumer = new Consumer( + new ConnectionFactory(config), + hostname, port, + exchangeName, + exchangeType, + shutdownListener, + initReconnectDelay, + passive, + durable, + configurationArguments) + startLink(consumer) + consumer + } + + def stopConnection(connection: FaultTolerantConnectionActor) = { + connection ! Stop + unlink(connection) + connections.remove(connection) + } + + override def shutdown = { + connections.values.asScala.foreach(_ ! Stop) + exit + } + + def receive = { + case _ => {} // ignore all messages + } + } sealed trait AMQPMessage private[akka] trait InternalAMQPMessage extends AMQPMessage + /** + * @author Jonas Bonér + */ class Message(val payload: Array[Byte], val routingKey: String, val mandatory: Boolean, @@ -59,12 +155,15 @@ object AMQP extends Actor { val properties: RabbitMQ.BasicProperties) extends AMQPMessage { override def toString(): String = "Message[payload=" + payload + - ", routingKey=" + routingKey + - ", mandatory=" + mandatory + - ", immediate=" + immediate + - ", properties=" + properties + "]" + ", routingKey=" + routingKey + + ", mandatory=" + mandatory + + ", immediate=" + immediate + + ", properties=" + properties + "]" } + /** + * @author Jonas Bonér + */ object Message { def unapply(message: Message): Option[Tuple5[AnyRef, String, Boolean, Boolean, RabbitMQ.BasicProperties]] = Some((message.payload, message.routingKey, message.mandatory, message.immediate, message.properties)) @@ -76,28 +175,31 @@ object AMQP extends Actor { new Message(payload, routingKey, false, false, null) } - case class MessageConsumerListener(queueName: String, - routingKey: String, - isUsingExistingQueue: Boolean, + /** + * @author Jonas Bonér + */ + case class MessageConsumerListener(queueName: String, + routingKey: String, + isUsingExistingQueue: Boolean, actor: Actor) extends AMQPMessage { - def this(queueName: String, routingKey: String, actor: Actor) = this(queueName, routingKey, false, actor) - + def this(queueName: String, routingKey: String, actor: Actor) = this (queueName, routingKey, false, actor) + private[akka] var tag: Option[String] = None - override def toString() = + override def toString() = "MessageConsumerListener[actor=" + actor + - ", queue=" + queueName + - ", routingKey=" + routingKey + - ", tag=" + tag + - ", isUsingExistingQueue=" + isUsingExistingQueue + "]" + ", queue=" + queueName + + ", routingKey=" + routingKey + + ", tag=" + tag + + ", isUsingExistingQueue=" + isUsingExistingQueue + "]" - def toString(exchangeName: String) = + def toString(exchangeName: String) = "MessageConsumerListener[actor=" + actor + - ", exchange=" + exchangeName + - ", queue=" + queueName + - ", routingKey=" + routingKey + - ", tag=" + tag + - ", isUsingExistingQueue=" + isUsingExistingQueue + "]" + ", exchange=" + exchangeName + + ", queue=" + queueName + + ", routingKey=" + routingKey + + ", tag=" + tag + + ", isUsingExistingQueue=" + isUsingExistingQueue + "]" /** * Hash code should only be based on on queue name and routing key. @@ -114,31 +216,32 @@ object AMQP extends Actor { */ override def equals(that: Any): Boolean = synchronized { that != null && - that.isInstanceOf[MessageConsumerListener] && - that.asInstanceOf[MessageConsumerListener].queueName== queueName && - that.asInstanceOf[MessageConsumerListener].routingKey == routingKey + that.isInstanceOf[MessageConsumerListener] && + that.asInstanceOf[MessageConsumerListener].queueName == queueName && + that.asInstanceOf[MessageConsumerListener].routingKey == routingKey } } object MessageConsumerListener { - def apply(queueName: String, routingKey: String, actor: Actor) = new MessageConsumerListener(queueName, routingKey, false, actor) + def apply(queueName: String, routingKey: String, actor: Actor) = + new MessageConsumerListener(queueName, routingKey, false, actor) } - + case object Stop extends AMQPMessage - + private[akka] case class UnregisterMessageConsumerListener(consumer: MessageConsumerListener) extends InternalAMQPMessage - + private[akka] case class Reconnect(delay: Long) extends InternalAMQPMessage - + private[akka] case class Failure(cause: Throwable) extends InternalAMQPMessage - + private[akka] class MessageNotDeliveredException( - val message: String, - val replyCode: Int, - val replyText: String, - val exchange: String, - val routingKey: String, - val properties: RabbitMQ.BasicProperties, - val body: Array[Byte]) extends RuntimeException(message) + val message: String, + val replyCode: Int, + val replyText: String, + val exchange: String, + val routingKey: String, + val properties: RabbitMQ.BasicProperties, + val body: Array[Byte]) extends RuntimeException(message) sealed trait ExchangeType object ExchangeType { @@ -156,84 +259,29 @@ object AMQP extends Actor { } } - def newProducer( - config: ConnectionParameters, - hostname: String, - port: Int, - exchangeName: String, - returnListener: Option[ReturnListener], - shutdownListener: Option[ShutdownListener], - initReconnectDelay: Long): Producer = { - val producer = new Producer( - new ConnectionFactory(config), - hostname, port, - exchangeName, - returnListener, - shutdownListener, - initReconnectDelay) - startLink(producer) - producer - } - - def newConsumer( - config: ConnectionParameters, - hostname: String, - port: Int, - exchangeName: String, - exchangeType: ExchangeType, - shutdownListener: Option[ShutdownListener], - initReconnectDelay: Long, - passive: Boolean, - durable: Boolean, - configurationArguments: Map[String, AnyRef]): Consumer = { - val consumer = new Consumer( - new ConnectionFactory(config), - hostname, port, - exchangeName, - exchangeType, - shutdownListener, - initReconnectDelay, - passive, - durable, - configurationArguments) - startLink(consumer) - consumer - } - - def stopConnection(connection: FaultTolerantConnectionActor) = { - connection ! Stop - unlink(connection) - connections.remove(connection) - } - - override def shutdown = { - connections.values.asScala.foreach(_ ! Stop) - exit - } - /** * @author Jonas Bonér */ - class Producer private[amqp] ( - val connectionFactory: ConnectionFactory, - val hostname: String, - val port: Int, - val exchangeName: String, - val returnListener: Option[ReturnListener], - val shutdownListener: Option[ShutdownListener], - val initReconnectDelay: Long) - extends FaultTolerantConnectionActor { - + class Producer private[amqp]( + val connectionFactory: ConnectionFactory, + val hostname: String, + val port: Int, + val exchangeName: String, + val returnListener: Option[ReturnListener], + val shutdownListener: Option[ShutdownListener], + val initReconnectDelay: Long) + extends FaultTolerantConnectionActor { setupChannel log.info("AMQP.Producer [%s] is started", toString) def newRpcClient(routingKey: String): RpcClient = new RpcClient(channel, exchangeName, routingKey) - + def receive = { - case message @ Message(payload, routingKey, mandatory, immediate, properties) => + case message@Message(payload, routingKey, mandatory, immediate, properties) => log.debug("Sending message [%s]", message) - channel.basicPublish(exchangeName, routingKey, mandatory, immediate, properties, payload.asInstanceOf[Array[Byte]]) + channel.basicPublish( + exchangeName, routingKey, mandatory, immediate, properties, payload.asInstanceOf[Array[Byte]]) case Stop => disconnect exit @@ -246,18 +294,18 @@ object AMQP extends Actor { case Some(listener) => channel.setReturnListener(listener) case None => channel.setReturnListener(new ReturnListener() { def handleBasicReturn( - replyCode: Int, - replyText: String, - exchange: String, - routingKey: String, - properties: RabbitMQ.BasicProperties, - body: Array[Byte]) = { + replyCode: Int, + replyText: String, + exchange: String, + routingKey: String, + properties: RabbitMQ.BasicProperties, + body: Array[Byte]) = { throw new MessageNotDeliveredException( "Could not deliver message [" + body + - "] with reply code [" + replyCode + - "] with reply text [" + replyText + - "] and routing key [" + routingKey + - "] to exchange [" + exchange + "]", + "] with reply code [" + replyCode + + "] with reply text [" + replyText + + "] and routing key [" + routingKey + + "] to exchange [" + exchange + "]", replyCode, replyText, exchange, routingKey, properties, body) } }) @@ -267,25 +315,26 @@ object AMQP extends Actor { override def toString(): String = "AMQP.Producer[hostname=" + hostname + - ", port=" + port + - ", exchange=" + exchangeName + "]" + ", port=" + port + + ", exchange=" + exchangeName + "]" } /** * @author Jonas Bonér */ - class Consumer private[amqp] ( - val connectionFactory: ConnectionFactory, - val hostname: String, - val port: Int, - val exchangeName: String, - val exchangeType: ExchangeType, - val shutdownListener: Option[ShutdownListener], - val initReconnectDelay: Long, - val passive: Boolean, - val durable: Boolean, - val configurationArguments: Map[java.lang.String, Object]) - extends FaultTolerantConnectionActor { consumer: Consumer => + class Consumer private[amqp]( + val connectionFactory: ConnectionFactory, + val hostname: String, + val port: Int, + val exchangeName: String, + val exchangeType: ExchangeType, + val shutdownListener: Option[ShutdownListener], + val initReconnectDelay: Long, + val passive: Boolean, + val durable: Boolean, + val configurationArguments: Map[java.lang.String, Object]) + extends FaultTolerantConnectionActor { + consumer: Consumer => faultHandler = Some(OneForOneStrategy(5, 5000)) trapExit = List(classOf[Throwable]) @@ -302,7 +351,7 @@ object AMQP extends Actor { body(requestBody, replyProperties) } } - } + } def receive = { case listener: MessageConsumerListener => @@ -312,32 +361,34 @@ object AMQP extends Actor { case UnregisterMessageConsumerListener(listener) => unregisterListener(listener) - - case Reconnect(delay) => + + case Reconnect(delay) => reconnect(delay) - case Failure(cause) => + case Failure(cause) => log.error(cause, "") throw cause - case Stop => + case Stop => listeners.elements.toList.map(_._2).foreach(unregisterListener(_)) disconnect exit - case message: Message => - handleIllegalMessage("AMQP.Consumer [" + this + "] can't be used to send messages, ignoring message [" + message + "]") + case message: Message => + handleIllegalMessage( + "AMQP.Consumer [" + this + "] can't be used to send messages, ignoring message [" + message + "]") - case unknown => - handleIllegalMessage("Unknown message [" + unknown + "] to AMQP Consumer [" + this + "]") + case unknown => + handleIllegalMessage( + "Unknown message [" + unknown + "] to AMQP Consumer [" + this + "]") } protected def setupChannel = { connection = connectionFactory.newConnection(hostname, port) channel = connection.createChannel channel.exchangeDeclare(exchangeName.toString, exchangeType.toString, - passive, durable, - configurationArguments.asJava) + passive, durable, + configurationArguments.asJava) listeners.elements.toList.map(_._2).foreach(registerListener) if (shutdownListener.isDefined) connection.addShutdownListener(shutdownListener.get) } @@ -352,12 +403,12 @@ object AMQP extends Actor { } log.debug("Binding new queue for MessageConsumerListener [%s]", listener.queueName) - channel.queueBind(listener.queueName, exchangeName, listener.routingKey) + channel.queueBind(listener.queueName, exchangeName, listener.routingKey) val listenerTag = channel.basicConsume(listener.queueName, true, new DefaultConsumer(channel) with Logging { - override def handleDelivery(tag: String, - envelope: Envelope, - properties: RabbitMQ.BasicProperties, + override def handleDelivery(tag: String, + envelope: Envelope, + properties: RabbitMQ.BasicProperties, payload: Array[Byte]) { try { val mandatory = false // FIXME: where to find out if it's mandatory? @@ -368,22 +419,27 @@ object AMQP extends Actor { log.debug("Acking message with delivery tag [%s]", deliveryTag) channel.basicAck(deliveryTag, false) } catch { - case cause => - log.error("Delivery of message to MessageConsumerListener [%s] failed due to [%s]", listener.toString(exchangeName), cause.toString) + case cause => + log.error( + "Delivery of message to MessageConsumerListener [%s] failed due to [%s]", + listener.toString(exchangeName), cause.toString) consumer ! Failure(cause) // pass on and re-throw exception in consumer actor to trigger restart and reconnect } } override def handleShutdownSignal(listenerTag: String, signal: ShutdownSignalException) = { def hasTag(listener: MessageConsumerListener, listenerTag: String): Boolean = { - if (listener.tag.isEmpty) throw new IllegalStateException("MessageConsumerListener [" + listener + "] does not have a tag") + if (listener.tag.isEmpty) throw new IllegalStateException( + "MessageConsumerListener [" + listener + "] does not have a tag") listener.tag.get == listenerTag } listeners.elements.toList.map(_._2).find(hasTag(_, listenerTag)) match { - case None => log.error("Could not find message listener for tag [%s]; can't shut listener down", listenerTag) + case None => log.error( + "Could not find message listener for tag [%s]; can't shut listener down", listenerTag) case Some(listener) => - log.warning("MessageConsumerListener [%s] is being shutdown by [%s] due to [%s]", - listener.toString(exchangeName), signal.getReference, signal.getReason) + log.warning( + "MessageConsumerListener [%s] is being shutdown by [%s] due to [%s]", + listener.toString(exchangeName), signal.getReference, signal.getReason) consumer ! UnregisterMessageConsumerListener(listener) } } @@ -393,11 +449,15 @@ object AMQP extends Actor { private def unregisterListener(listener: MessageConsumerListener) = { listeners.get(listener) match { - case None => log.warning("Can't unregister message consumer listener [%s]; no such listener", listener.toString(exchangeName)) + case None => log.warning( + "Can't unregister message consumer listener [%s]; no such listener", + listener.toString(exchangeName)) case Some(listener) => listeners - listener listener.tag match { - case None => log.warning("Can't unregister message consumer listener [%s]; no listener tag", listener.toString(exchangeName)) + case None => log.warning( + "Can't unregister message consumer listener [%s]; no listener tag", + listener.toString(exchangeName)) case Some(tag) => channel.basicCancel(tag) unlink(listener.actor) @@ -406,21 +466,24 @@ object AMQP extends Actor { } } } - + private def handleIllegalMessage(errorMessage: String) = { log.error(errorMessage) throw new IllegalArgumentException(errorMessage) } - + override def toString(): String = "AMQP.Consumer[hostname=" + hostname + - ", port=" + port + - ", exchange=" + exchangeName + - ", type=" + exchangeType + - ", passive=" + passive + - ", durable=" + durable + "]" + ", port=" + port + + ", exchange=" + exchangeName + + ", type=" + exchangeType + + ", passive=" + passive + + ", durable=" + durable + "]" } + /** + * @author Jonas Bonér + */ trait FaultTolerantConnectionActor extends Actor { val reconnectionTimer = new Timer @@ -435,29 +498,32 @@ object AMQP extends Actor { protected def setupChannel - def createQueue: String = channel.queueDeclare("", false, false, true, true, null).getQueue + def createQueue: String = + channel.queueDeclare("", false, false, true, true, null).getQueue - def createQueue(name: String) = channel.queueDeclare(name, false, false, true, true, null).getQueue + def createQueue(name: String) = + channel.queueDeclare(name, false, false, true, true, null).getQueue - def createQueue(name: String, durable: Boolean) = channel.queueDeclare(name, false, durable, true, true, null).getQueue + def createQueue(name: String, durable: Boolean) = + channel.queueDeclare(name, false, durable, true, true, null).getQueue - def createBindQueue: String = { + def createBindQueue: String = { val name = createQueue channel.queueBind(name, exchangeName, name) name } - def createBindQueue(name: String) { + def createBindQueue(name: String) { createQueue(name) channel.queueBind(name, exchangeName, name) } - def createBindQueue(name: String, durable: Boolean) { + def createBindQueue(name: String, durable: Boolean) { channel.queueDeclare(name, durable) channel.queueBind(name, exchangeName, name) } - def deleteQueue(name: String) { channel.queueDelete(name) } + def deleteQueue(name: String) {channel.queueDelete(name)} protected def disconnect = { try { @@ -492,10 +558,7 @@ object AMQP extends Actor { } override def preRestart(reason: AnyRef, config: Option[AnyRef]) = disconnect + override def postRestart(reason: AnyRef, config: Option[AnyRef]) = reconnect(initReconnectDelay) } - - def receive = { - case _ => {} // ignore all messages - } } diff --git a/akka-amqp/src/main/scala/ExampleSession.scala b/akka-amqp/src/main/scala/ExampleSession.scala index 574b825470..158dbe46d0 100644 --- a/akka-amqp/src/main/scala/ExampleSession.scala +++ b/akka-amqp/src/main/scala/ExampleSession.scala @@ -5,6 +5,7 @@ package se.scalablesolutions.akka.amqp import se.scalablesolutions.akka.actor.Actor +import se.scalablesolutions.akka.actor.Actor.Sender.Self import com.rabbitmq.client.ConnectionParameters diff --git a/akka-persistence/src/test/scala/AllTest.scala b/akka-persistence/src/test/scala/AllTest.scala index 60374da92d..2e9bc78178 100644 --- a/akka-persistence/src/test/scala/AllTest.scala +++ b/akka-persistence/src/test/scala/AllTest.scala @@ -1,6 +1,6 @@ package se.scalablesolutions.akka -import akka.state.{MongoStorageSpec, MongoPersistentActorSpec, CassandraPersistentActorSpec} +import se.scalablesolutions.akka.state.{MongoStorageSpec, MongoPersistentActorSpec, CassandraPersistentActorSpec} import junit.framework.Test import junit.framework.TestCase import junit.framework.TestSuite diff --git a/changes.xml b/changes.xml index 203bd588ac..658b8ab550 100644 --- a/changes.xml +++ b/changes.xml @@ -18,10 +18,12 @@ see http://maven.apache.org/plugins/maven-changes-plugin/usage.html for full gui Akka Release Notes - + Jonas Bonér - + MongoDB as Akka storage backend Transparent JSON serialization of Scala objects based on SJSON MongoDB backed actor example @@ -30,17 +32,17 @@ see http://maven.apache.org/plugins/maven-changes-plugin/usage.html for full gui Support for using Scala XML tags in RESTful Actors (scala-jersey) Support for Comet Actors using Atmosphere Kerberos/SPNEGO support for Security module - AMQP integration; abstracted as actors in a supervisor hierarchy. Impl AMQP 0.9.1 Rewritten STM, now integrated with Multiverse STM Added STM API for atomic {..} and run {..} orElse {..} Added STM retry Complete rewrite of the persistence transaction management, now based on Unit of Work and Multiverse STM Monadic API to TransactionalRef (use it in for-comprehension) - Lightweight actor syntax 'actor { case _ => .. }' + Lightweight actor syntax using one of the Actor.actor(..) methods. F.e: 'actor { case _ => .. }' New Scala JSON parser based on sjson - Upgraded to Netty 3.2 and Protobuf 2.2 + Added zlib compression to remote actors + Added implicit sender reference for fire-forget ('!') message sends Monadic API to TransactionalRef (use it in for-comprehension) - Smoother web app integration; just add akka.conf to WEB-INF/classes, no need for AKKA_HOME + Smoother web app integration; just add akka.conf to the classpath (WEB-INF/classes), no need for AKKA_HOME or -Dakka.conf=.. Modularization of distribution into a thin core (actors, remoting and STM) and the rest in submodules JSON serialization for Java objects (using Jackson) JSON serialization for Scala objects (using SJSON) @@ -48,22 +50,29 @@ see http://maven.apache.org/plugins/maven-changes-plugin/usage.html for full gui Protobuf serialization for Java and Scala objects SBinary serialization for Scala objects Protobuf as remote protocol + AMQP integration; abstracted as actors in a supervisor hierarchy. Impl AMQP 0.9.1 Updated Cassandra integration and CassandraSession API to v0.4 Added CassandraSession API (with socket pooling) wrapping Cassandra's Thrift API in Scala and Java APIs CassandraStorage is now works with external Cassandra cluster - Removed embedded Cassandra mode - Removed startup scripts and lib dir - Removed 'Transient' Actors and restart timeout ActorRegistry for retrieving Actor instances by class name and by id SchedulerActor for scheduling periodic tasks Now start up kernel with 'java -jar dist/akka-0.6.jar' - Concurrent mode is now per actor basis - Fixed dispatcher bug - Cleaned up Maven scripts and distribution in general Added mailing list: akka-user@googlegroups.com Improved and restructured documentation New URL: http://akkasource.org - Fixed many many bugs and minor issues + Enhanced trapping of failures: 'trapExit = List(classOf[..], classOf[..])' + Upgraded to Netty 3.2, Protobuf 2.2, ScalaTest 1.0, Jersey 1.1.3, Atmosphere 0.4.1, Cassandra 0.4.1, Configgy 1.4 + Concurrent mode is now per actor basis + Remote actors are now defined by their UUID (not class name) + Fixed dispatcher bug + Cleaned up Maven scripts and distribution in general + Fixed many many bugs and minor issues + Fixed inconsistencies and uglyness in Actors API + Removed embedded Cassandra mode + Removed the !? method in Actor (synchronous message send, since it's evil. Use !! with time-out instead. + Removed startup scripts and lib dir + Removed the 'Transient' life-cycle scope since to close to 'Temporary' in semantics. + Removed 'Transient' Actors and restart timeout From b0db0b416546ff157cfec516fe22fec8f5e1f4f8 Mon Sep 17 00:00:00 2001 From: jboner Date: Mon, 23 Nov 2009 20:23:18 +0100 Subject: [PATCH 11/20] reverted back to original mongodb test, still failing though --- .../test/scala/MongoPersistentActorSpec.scala | 162 ++---------------- 1 file changed, 10 insertions(+), 152 deletions(-) diff --git a/akka-persistence/src/test/scala/MongoPersistentActorSpec.scala b/akka-persistence/src/test/scala/MongoPersistentActorSpec.scala index b04b2d04b4..67b116863f 100644 --- a/akka-persistence/src/test/scala/MongoPersistentActorSpec.scala +++ b/akka-persistence/src/test/scala/MongoPersistentActorSpec.scala @@ -1,12 +1,15 @@ package se.scalablesolutions.akka.state -import se.scalablesolutions.akka.actor.Actor import junit.framework.TestCase + import org.junit.{Test, Before} import org.junit.Assert._ -import _root_.dispatch.json._ + +import _root_.dispatch.json.{JsNumber, JsValue} import _root_.dispatch.json.Js._ +import se.scalablesolutions.akka.actor.Actor + /** * A persistent actor based on MongoDB storage. *

@@ -28,155 +31,12 @@ case object LogSize class BankAccountActor extends Actor { makeTransactionRequired + private val accountState = + PersistentState.newMap(MongoStorageConfig()) + private val txnLog = + PersistentState.newVector(MongoStorageConfig()) - private lazy val accountState: PersistentMap = PersistentState.newMap(MongoStorageConfig()) - private lazy val txnLog: PersistentVector = PersistentState.newVector(MongoStorageConfig()) - - def receive = { - // check balance - case Balance(accountNo) => - txnLog.add("Balance:" + accountNo) - reply(accountState.get(accountNo).get) - - // debit amount: can fail - case Debit(accountNo, amount, failer) => - txnLog.add("Debit:" + accountNo + " " + amount) - val m: BigInt = - accountState.get(accountNo) match { - case None => 0 - case Some(v) => v.asInstanceOf[BigInt] - } - accountState.put(accountNo, (m - amount)) - if (amount > m) - failer !! "Failure" - reply(m - amount) - - // many debits: can fail - // demonstrates true rollback even if multiple puts have been done - case MultiDebit(accountNo, amounts, failer) => - txnLog.add("MultiDebit:" + accountNo + " " + amounts.map(_.intValue).foldLeft(0)(_ + _)) - val m: BigInt = - accountState.get(accountNo) match { - case None => 0 - case Some(v) => BigInt(v.asInstanceOf[String]) - } - var bal: BigInt = 0 - amounts.foreach {amount => - bal = bal + amount - accountState.put(accountNo, (m - bal)) - } - if (bal > m) failer !! "Failure" - reply(m - bal) - - // credit amount - case Credit(accountNo, amount) => - txnLog.add("Credit:" + accountNo + " " + amount) - val m: BigInt = - accountState.get(accountNo) match { - case None => 0 - case Some(v) => v.asInstanceOf[BigInt] - } - accountState.put(accountNo, (m + amount)) - reply(m + amount) - - case LogSize => - reply(txnLog.length.asInstanceOf[AnyRef]) - } -} - -class MongoPersistentActorSpec extends TestCase { - @Test - def testSuccessfulDebit = { - val bactor = new BankAccountActor - bactor.start - val failer = new PersistentFailerActor - failer.start - bactor !! Credit("a-123", 5000) - bactor !! Debit("a-123", 3000, failer) - val b = (bactor !! Balance("a-123")) - assertTrue(b.isDefined) - assertEquals(BigInt(2000), b.get) - - bactor !! Credit("a-123", 7000) - val b1 = (bactor !! Balance("a-123")) - assertTrue(b1.isDefined) - assertEquals(BigInt(9000), b1.get) - - bactor !! Debit("a-123", 8000, failer) - val b2 = (bactor !! Balance("a-123")) - assertTrue(b2.isDefined) - assertEquals(BigInt(1000), b2.get) - assertEquals(7, (bactor !! LogSize).get) - } - - @Test - def testUnsuccessfulDebit = { - val bactor = new BankAccountActor - bactor.start - bactor !! Credit("a-123", 5000) - - val b = (bactor !! Balance("a-123")) - assertTrue(b.isDefined) - assertEquals(BigInt(5000), b.get) - - val failer = new PersistentFailerActor - failer.start - try { - bactor !! Debit("a-123", 7000, failer) - fail("should throw exception") - } catch { case e: RuntimeException => {}} - - val b1 = (bactor !! Balance("a-123")) - assertTrue(b1.isDefined) - assertEquals(BigInt(5000), b1.get) - - // should not count the failed one - assertEquals(3, (bactor !! LogSize).get) - } - - @Test - def testUnsuccessfulMultiDebit = { - val bactor = new BankAccountActor - bactor.start - bactor !! Credit("a-123", 5000) - val b = (bactor !! Balance("a-123")) - assertTrue(b.isDefined) - assertEquals(BigInt(5000), b.get) - - val failer = new PersistentFailerActor - failer.start - try { - bactor !! MultiDebit("a-123", List(500, 2000, 1000, 3000), failer) - fail("should throw exception") - } catch { case e: RuntimeException => {}} - - val b1 = (bactor !! Balance("a-123")) - assertTrue(b1.isDefined) - assertEquals(BigInt(5000), b1.get) - - // should not count the failed one - assertEquals(3, (bactor !! LogSize).get) - } -} - -/* -case class Balance(accountNo: String) -case class Debit(accountNo: String, amount: BigInt, failer: Actor) -case class MultiDebit(accountNo: String, amounts: List[BigInt], failer: Actor) -case class Credit(accountNo: String, amount: BigInt) -case object LogSize - -class BankAccountActor extends Actor { - makeTransactionRequired - - private var accountState: PersistentMap = _ - private var txnLog: PersistentVector = _ - override def initializeTransactionalState = { - accountState = PersistentState.newMap(MongoStorageConfig()) - txnLog = PersistentState.newVector(MongoStorageConfig()) - } - - def receive = { + def receive: PartialFunction[Any, Unit] = { // check balance case Balance(accountNo) => txnLog.add("Balance:" + accountNo) @@ -189,7 +49,6 @@ class BankAccountActor extends Actor { accountState.get(accountNo) match { case None => 0 case Some(v) => { - println("======= " + v) val JsNumber(n) = v.asInstanceOf[JsValue] BigInt(n.toString) } @@ -309,4 +168,3 @@ class MongoPersistentActorSpec extends TestCase { assertEquals(3, (bactor !! LogSize).get) } } -*/ \ No newline at end of file From d1d3788b8528b92179e70724906ce8f1c8fd0679 Mon Sep 17 00:00:00 2001 From: jboner Date: Tue, 24 Nov 2009 07:58:14 +0100 Subject: [PATCH 12/20] cleaned up and fixed broken error logging --- akka-actors/src/main/scala/actor/Actor.scala | 6 ++--- akka-amqp/src/main/scala/AMQP.scala | 6 ++--- akka-kernel/src/main/scala/Kernel.scala | 2 +- akka-security/src/main/scala/Security.scala | 6 +++-- akka-util/src/main/scala/Logging.scala | 23 +++++++------------- 5 files changed, 19 insertions(+), 24 deletions(-) diff --git a/akka-actors/src/main/scala/actor/Actor.scala b/akka-actors/src/main/scala/actor/Actor.scala index ea2c64d880..6fa50ea106 100644 --- a/akka-actors/src/main/scala/actor/Actor.scala +++ b/akka-actors/src/main/scala/actor/Actor.scala @@ -738,7 +738,7 @@ trait Actor extends Logging with TransactionManagement { else dispatch(messageHandle) } catch { case e => - log.error(e, e.getMessage) // for logging the exception to log file + log.error(e, "Could not invoke actor [%s]", this) throw e } } @@ -755,7 +755,7 @@ trait Actor extends Logging with TransactionManagement { else throw new IllegalArgumentException("No handler matching message [" + message + "] in " + toString) } catch { case e => - log.error(e, e.getMessage) + log.error(e, "Could not invoke actor [%s]", this) // FIXME to fix supervisor restart of remote actor for oneway calls, inject a supervisor proxy that can send notification back to client if (_supervisor.isDefined) _supervisor.get ! Exit(this, e) if (senderFuture.isDefined) senderFuture.get.completeWithException(this, e) @@ -795,7 +795,7 @@ trait Actor extends Logging with TransactionManagement { } else proceed } catch { case e => - log.error(e, e.getMessage) + log.error(e, "Could not invoke actor [%s]", this) if (senderFuture.isDefined) senderFuture.get.completeWithException(this, e) clearTransaction // need to clear currentTransaction before call to supervisor // FIXME to fix supervisor restart of remote actor for oneway calls, inject a supervisor proxy that can send notification back to client diff --git a/akka-amqp/src/main/scala/AMQP.scala b/akka-amqp/src/main/scala/AMQP.scala index af56bfc8a1..462e65f854 100644 --- a/akka-amqp/src/main/scala/AMQP.scala +++ b/akka-amqp/src/main/scala/AMQP.scala @@ -366,7 +366,7 @@ object AMQP { reconnect(delay) case Failure(cause) => - log.error(cause, "") + log.error(cause, "Error in AMQP consumer") throw cause case Stop => @@ -421,8 +421,8 @@ object AMQP { } catch { case cause => log.error( - "Delivery of message to MessageConsumerListener [%s] failed due to [%s]", - listener.toString(exchangeName), cause.toString) + cause, "Delivery of message to MessageConsumerListener [%s] failed", + listener.toString(exchangeName)) consumer ! Failure(cause) // pass on and re-throw exception in consumer actor to trigger restart and reconnect } } diff --git a/akka-kernel/src/main/scala/Kernel.scala b/akka-kernel/src/main/scala/Kernel.scala index e4f66a9050..7e988d1ede 100644 --- a/akka-kernel/src/main/scala/Kernel.scala +++ b/akka-kernel/src/main/scala/Kernel.scala @@ -94,7 +94,7 @@ object Kernel extends Logging { val DEPLOY = HOME.get + "/deploy" val DEPLOY_DIR = new File(DEPLOY) if (!DEPLOY_DIR.exists) { - log.error("Could not find a deploy directory at [" + DEPLOY + "]") + log.error("Could not find a deploy directory at [%s]", DEPLOY) System.exit(-1) } val toDeploy = for (f <- DEPLOY_DIR.listFiles().toArray.toList.asInstanceOf[List[File]]) yield f.toURL diff --git a/akka-security/src/main/scala/Security.scala b/akka-security/src/main/scala/Security.scala index 6efa5bdcce..f6f2b939a1 100644 --- a/akka-security/src/main/scala/Security.scala +++ b/akka-security/src/main/scala/Security.scala @@ -91,7 +91,7 @@ class AkkaSecurityFilterFactory extends ResourceFilterFactory with Logging { case r if r.isInstanceOf[Response] => throw new WebApplicationException(r.asInstanceOf[Response]) case x => { - log.error("Authenticator replied with unexpected result: ", x); + log.error("Authenticator replied with unexpected result [%s]", x); throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR) } } @@ -100,7 +100,9 @@ class AkkaSecurityFilterFactory extends ResourceFilterFactory with Logging { } } - lazy val authenticatorFQN = Config.config.getString("akka.rest.authenticator").getOrElse(throw new IllegalStateException("akka.rest.authenticator")) + lazy val authenticatorFQN = + Config.config.getString("akka.rest.authenticator") + .getOrElse(throw new IllegalStateException("akka.rest.authenticator")) /** * Currently we always take the first, since there usually should be at most one authentication actor, but a round-robin diff --git a/akka-util/src/main/scala/Logging.scala b/akka-util/src/main/scala/Logging.scala index 39f2afee21..feb088ac2b 100644 --- a/akka-util/src/main/scala/Logging.scala +++ b/akka-util/src/main/scala/Logging.scala @@ -4,11 +4,8 @@ package se.scalablesolutions.akka.util -import java.util.logging.Level -import net.lag.configgy.Config import net.lag.logging.Logger -import java.util.Date import java.io.StringWriter; import java.io.PrintWriter; import java.net.InetAddress; @@ -16,15 +13,11 @@ import java.net.UnknownHostException; /** * Base trait for all classes that wants to be able use the logging infrastructure. - * + * * @author Jonas Bonér */ trait Logging { - @transient var log = { - val log = Logger.get(this.getClass.getName) - //0log.setLevel(Level.ALL) - log - } + @transient @volatile var log = Logger.get(this.getClass.getName) } /** @@ -34,7 +27,7 @@ trait Logging { * It keeps track of the exception is logged or not and also stores the unique id, * so that it can be carried all along to the client tier and displayed to the end user. * The end user can call up the customer support using this number. - * + * * @author Jonas Bonér */ class LoggableException extends Exception with Logging { @@ -50,14 +43,14 @@ class LoggableException extends Exception with Logging { def logException = synchronized { if (!isLogged) { originalException match { - case Some(e) => log.error("Logged Exception [%s] %s", uniqueId, getStackTrace(e)) - case None => log.error("Logged Exception [%s] %s", uniqueId, getStackTrace(this)) + case Some(e) => log.error("Logged Exception [%s] %s", uniqueId, getStackTraceAsString(e)) + case None => log.error("Logged Exception [%s] %s", uniqueId, getStackTraceAsString(this)) } isLogged = true } - } + } - def getExceptionID: String = { + private def getExceptionID: String = { val hostname: String = try { InetAddress.getLocalHost.getHostName } catch { @@ -68,7 +61,7 @@ class LoggableException extends Exception with Logging { hostname + "_" + System.currentTimeMillis } - def getStackTrace(exception: Throwable): String = { + private def getStackTraceAsString(exception: Throwable): String = { val sw = new StringWriter val pw = new PrintWriter(sw) exception.printStackTrace(pw) From 93200be8364e874301b651934ad59e9a5c17cb21 Mon Sep 17 00:00:00 2001 From: jboner Date: Tue, 24 Nov 2009 17:41:08 +0100 Subject: [PATCH 13/20] changed remote server API to allow creating multiple servers (RemoteServer) or one (RemoteServerNode), also added a shutdown method --- akka-actors/pom.xml | 10 +- .../src/main/scala/nio/RemoteClient.scala | 8 +- .../src/main/scala/nio/RemoteServer.scala | 64 ++++++++-- .../src/test/scala/RemoteActorTest.scala | 4 +- .../src/test/scala/RemoteSupervisorTest.scala | 4 +- akka-amqp/pom.xml | 8 +- akka-camel/pom.xml | 8 +- akka-fun-test-java/pom.xml | 4 +- .../akka/api/RemoteInMemoryStateTest.java | 5 +- akka-kernel/pom.xml | 30 ++--- akka-kernel/src/main/scala/Kernel.scala | 4 +- akka-persistence/pom.xml | 22 +++- akka-rest/pom.xml | 8 +- akka-samples-java/pom.xml | 28 ++--- akka-samples-lift/pom.xml | 24 ++-- akka-samples-scala/pom.xml | 28 ++--- akka-samples-security/pom.xml | 28 ++--- akka-security/pom.xml | 36 +++--- akka-util/pom.xml | 4 +- .../akka/nio/RemoteServer$object.html | 2 +- .../akka/nio/RemoteServerHandler.html | 2 +- .../akka/nio/RemoteServerPipelineFactory.html | 2 +- pom.xml | 115 ++++++++++++++---- 23 files changed, 288 insertions(+), 160 deletions(-) diff --git a/akka-actors/pom.xml b/akka-actors/pom.xml index 30362fefff..b3dd417381 100644 --- a/akka-actors/pom.xml +++ b/akka-actors/pom.xml @@ -19,18 +19,18 @@ akka-util-java - se.scalablesolutions.akka - 0.6 + ${project.groupId} + ${project.version} akka-util - se.scalablesolutions.akka - 0.6 + ${project.groupId} + ${project.version} org.scala-lang scala-library - 2.7.5 + ${scala.version} org.codehaus.aspectwerkz diff --git a/akka-actors/src/main/scala/nio/RemoteClient.scala b/akka-actors/src/main/scala/nio/RemoteClient.scala index 658e400a65..3743699b3f 100644 --- a/akka-actors/src/main/scala/nio/RemoteClient.scala +++ b/akka-actors/src/main/scala/nio/RemoteClient.scala @@ -6,24 +6,24 @@ package se.scalablesolutions.akka.nio import scala.collection.mutable.HashMap -import protobuf.RemoteProtocol.{RemoteRequest, RemoteReply} +import se.scalablesolutions.akka.nio.protobuf.RemoteProtocol.{RemoteRequest, RemoteReply} import se.scalablesolutions.akka.actor.{Exit, Actor} import se.scalablesolutions.akka.dispatch.{DefaultCompletableFutureResult, CompletableFutureResult} import se.scalablesolutions.akka.util.Logging import se.scalablesolutions.akka.Config.config -import org.jboss.netty.bootstrap.ClientBootstrap import org.jboss.netty.channel._ import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory +import org.jboss.netty.bootstrap.ClientBootstrap import org.jboss.netty.handler.codec.frame.{LengthFieldBasedFrameDecoder, LengthFieldPrepender} +import org.jboss.netty.handler.codec.compression.{ZlibDecoder, ZlibEncoder} import org.jboss.netty.handler.codec.protobuf.{ProtobufDecoder, ProtobufEncoder} import org.jboss.netty.handler.timeout.ReadTimeoutHandler import org.jboss.netty.util.{TimerTask, Timeout, HashedWheelTimer} import java.net.InetSocketAddress import java.util.concurrent.{TimeUnit, Executors, ConcurrentMap, ConcurrentHashMap} -import org.jboss.netty.handler.codec.compression.{ZlibDecoder, ZlibEncoder} - + /** * @author Jonas Bonér */ diff --git a/akka-actors/src/main/scala/nio/RemoteServer.scala b/akka-actors/src/main/scala/nio/RemoteServer.scala index fd770bc6f5..2ffe0e1f1a 100755 --- a/akka-actors/src/main/scala/nio/RemoteServer.scala +++ b/akka-actors/src/main/scala/nio/RemoteServer.scala @@ -21,11 +21,34 @@ import org.jboss.netty.handler.codec.protobuf.{ProtobufDecoder, ProtobufEncoder} import org.jboss.netty.handler.codec.compression.{ZlibEncoder, ZlibDecoder} /** + * Use this object if you need a single remote server on a specific node. + * + *

+ * RemoteServerNode.start
+ * 
+ * + * If you need to create more than one, then you can use the RemoteServer: + * + *
+ * val server = new RemoteServer
+ * server.start
+ * 
+ * * @author Jonas Bonér */ -object RemoteServer extends Logging { +object RemoteServerNode extends RemoteServer + +/** + * This object holds configuration variables. + * + * @author Jonas Bonér + */ +object RemoteServer { val HOSTNAME = config.getString("akka.remote.server.hostname", "localhost") val PORT = config.getInt("akka.remote.server.port", 9999) + + val CONNECTION_TIMEOUT_MILLIS = config.getInt("akka.remote.server.connection-timeout", 1000) + val COMPRESSION_SCHEME = config.getString("akka.remote.compression-scheme", "zlib") val ZLIB_COMPRESSION_LEVEL = { val level = config.getInt("akka.remote.zlib-compression-level", 6) @@ -33,11 +56,29 @@ object RemoteServer extends Logging { "zlib compression level has to be within 1-9, with 1 being fastest and 9 being the most compressed") level } +} - val CONNECTION_TIMEOUT_MILLIS = config.getInt("akka.remote.server.connection-timeout", 1000) +/** + * Use this class if you need a more than one remote server on a specific node. + * + *
+ * val server = new RemoteServer
+ * server.start
+ * 
+ * + * If you need to create more than one, then you can use the RemoteServer: + * + *
+ * RemoteServerNode.start
+ * 
+ * + * @author Jonas Bonér + */ +class RemoteServer extends Logging { + val name = "RemoteServer@" + hostname + ":" + port - private var hostname = HOSTNAME - private var port = PORT + private var hostname = RemoteServer.HOSTNAME + private var port = RemoteServer.PORT @volatile private var isRunning = false @volatile private var isConfigured = false @@ -48,13 +89,11 @@ object RemoteServer extends Logging { private val bootstrap = new ServerBootstrap(factory) - def name = "RemoteServer@" + hostname + ":" + port - def start: Unit = start(None) - def start(loader: Option[ClassLoader]): Unit = start(HOSTNAME, PORT, loader) + def start(loader: Option[ClassLoader]): Unit = start(hostname, port, loader) - def start(hostname: String, port: Int): Unit = start(hostname, port, None) + def start(_hostname: String, _port: Int): Unit = start(_hostname, _port, None) def start(_hostname: String, _port: Int, loader: Option[ClassLoader]): Unit = synchronized { if (!isRunning) { @@ -62,15 +101,20 @@ object RemoteServer extends Logging { port = _port log.info("Starting remote server at [%s:%s]", hostname, port) bootstrap.setPipelineFactory(new RemoteServerPipelineFactory(name, loader)) + // FIXME make these RemoteServer options configurable bootstrap.setOption("child.tcpNoDelay", true) bootstrap.setOption("child.keepAlive", true) bootstrap.setOption("child.reuseAddress", true) - bootstrap.setOption("child.connectTimeoutMillis", CONNECTION_TIMEOUT_MILLIS) + bootstrap.setOption("child.connectTimeoutMillis", RemoteServer.CONNECTION_TIMEOUT_MILLIS) bootstrap.bind(new InetSocketAddress(hostname, port)) isRunning = true } } + + def shutdown = { + bootstrap.releaseExternalResources + } } /** @@ -78,6 +122,8 @@ object RemoteServer extends Logging { */ class RemoteServerPipelineFactory(name: String, loader: Option[ClassLoader]) extends ChannelPipelineFactory { + import RemoteServer._ + def getPipeline: ChannelPipeline = { val pipeline = Channels.pipeline() RemoteServer.COMPRESSION_SCHEME match { diff --git a/akka-actors/src/test/scala/RemoteActorTest.scala b/akka-actors/src/test/scala/RemoteActorTest.scala index 884a0d007f..f0ab401eac 100644 --- a/akka-actors/src/test/scala/RemoteActorTest.scala +++ b/akka-actors/src/test/scala/RemoteActorTest.scala @@ -3,9 +3,9 @@ package se.scalablesolutions.akka.actor import java.util.concurrent.TimeUnit import junit.framework.TestCase -import se.scalablesolutions.akka.nio.{RemoteServer, RemoteClient} import org.scalatest.junit.JUnitSuite import org.junit.Test +import se.scalablesolutions.akka.nio.{RemoteServerNode, RemoteServer, RemoteClient} object Global { var oneWay = "nada" @@ -32,7 +32,7 @@ class RemoteActorTest extends JUnitSuite { akka.Config.config new Thread(new Runnable() { def run = { - RemoteServer.start + RemoteServerNode.start } }).start Thread.sleep(1000) diff --git a/akka-actors/src/test/scala/RemoteSupervisorTest.scala b/akka-actors/src/test/scala/RemoteSupervisorTest.scala index ac6f1777ab..42a8837db3 100644 --- a/akka-actors/src/test/scala/RemoteSupervisorTest.scala +++ b/akka-actors/src/test/scala/RemoteSupervisorTest.scala @@ -5,11 +5,11 @@ package se.scalablesolutions.akka.actor import se.scalablesolutions.akka.serialization.BinaryString -import se.scalablesolutions.akka.nio.{RemoteClient, RemoteServer} import se.scalablesolutions.akka.config.ScalaConfig._ import org.scalatest.junit.JUnitSuite import org.junit.Test +import se.scalablesolutions.akka.nio.{RemoteServerNode, RemoteClient, RemoteServer} object Log { var messageLog: String = "" @@ -25,7 +25,7 @@ class RemoteSupervisorTest extends JUnitSuite { akka.Config.config new Thread(new Runnable() { def run = { - RemoteServer.start + RemoteServerNode.start } }).start Thread.sleep(1000) diff --git a/akka-amqp/pom.xml b/akka-amqp/pom.xml index 5199ed0dc3..323f90a0e4 100644 --- a/akka-amqp/pom.xml +++ b/akka-amqp/pom.xml @@ -17,13 +17,13 @@ akka-util - se.scalablesolutions.akka - 0.6 + ${project.groupId} + ${project.version} akka-actors - se.scalablesolutions.akka - 0.6 + ${project.groupId} + ${project.version} com.rabbitmq diff --git a/akka-camel/pom.xml b/akka-camel/pom.xml index 797b8fef53..a862e8f64f 100644 --- a/akka-camel/pom.xml +++ b/akka-camel/pom.xml @@ -19,13 +19,13 @@ akka-util - se.scalablesolutions.akka - 0.6 + ${project.groupId} + ${project.version} akka-actors - se.scalablesolutions.akka - 0.6 + ${project.groupId} + ${project.version} org.apache.camel diff --git a/akka-fun-test-java/pom.xml b/akka-fun-test-java/pom.xml index 0cba842396..3a0fc927eb 100644 --- a/akka-fun-test-java/pom.xml +++ b/akka-fun-test-java/pom.xml @@ -17,8 +17,8 @@ akka-kernel - se.scalablesolutions.akka - 0.6 + ${project.groupId} + ${project.version} com.sun.grizzly diff --git a/akka-fun-test-java/src/test/java/se/scalablesolutions/akka/api/RemoteInMemoryStateTest.java b/akka-fun-test-java/src/test/java/se/scalablesolutions/akka/api/RemoteInMemoryStateTest.java index 62050ea03e..3703efb43a 100644 --- a/akka-fun-test-java/src/test/java/se/scalablesolutions/akka/api/RemoteInMemoryStateTest.java +++ b/akka-fun-test-java/src/test/java/se/scalablesolutions/akka/api/RemoteInMemoryStateTest.java @@ -7,7 +7,8 @@ package se.scalablesolutions.akka.api; import se.scalablesolutions.akka.Config; import se.scalablesolutions.akka.actor.ActiveObject; import se.scalablesolutions.akka.config.ActiveObjectConfigurator; -import se.scalablesolutions.akka.nio.RemoteServer; +import se.scalablesolutions.akka.nio.RemoteServerNode; + import junit.framework.TestCase; public class RemoteInMemoryStateTest extends TestCase { @@ -16,7 +17,7 @@ public class RemoteInMemoryStateTest extends TestCase { static { new Thread(new Runnable() { public void run() { - RemoteServer.start(); + RemoteServerNode.start(); } }).start(); try { Thread.currentThread().sleep(1000); } catch (Exception e) {} diff --git a/akka-kernel/pom.xml b/akka-kernel/pom.xml index 6e430c08c6..93fce3f319 100755 --- a/akka-kernel/pom.xml +++ b/akka-kernel/pom.xml @@ -19,40 +19,40 @@ akka-actors - se.scalablesolutions.akka - 0.6 + ${project.groupId} + ${project.version} akka-persistence - se.scalablesolutions.akka - 0.6 + ${project.groupId} + ${project.version} akka-rest - se.scalablesolutions.akka - 0.6 + ${project.groupId} + ${project.version} akka-amqp - se.scalablesolutions.akka - 0.6 + ${project.groupId} + ${project.version} akka-camel - se.scalablesolutions.akka - 0.6 + ${project.groupId} + ${project.version} akka-security - se.scalablesolutions.akka - 0.6 + ${project.groupId} + ${project.version} org.scala-lang scala-library - 2.7.5 + ${scala.version} org.codehaus.aspectwerkz @@ -277,8 +277,8 @@ install - + diff --git a/akka-kernel/src/main/scala/Kernel.scala b/akka-kernel/src/main/scala/Kernel.scala index 7e988d1ede..295a1d3b38 100644 --- a/akka-kernel/src/main/scala/Kernel.scala +++ b/akka-kernel/src/main/scala/Kernel.scala @@ -12,7 +12,7 @@ import javax.ws.rs.core.UriBuilder import java.io.File import java.net.URLClassLoader -import se.scalablesolutions.akka.nio.RemoteServer +import se.scalablesolutions.akka.nio.RemoteServerNode import se.scalablesolutions.akka.util.Logging /** @@ -54,7 +54,7 @@ object Kernel extends Logging { def startRemoteService = { // FIXME manage remote serve thread for graceful shutdown val remoteServerThread = new Thread(new Runnable() { - def run = RemoteServer.start(applicationLoader) + def run = RemoteServerNode.start(applicationLoader) }, "Akka Remote Service") remoteServerThread.start } diff --git a/akka-persistence/pom.xml b/akka-persistence/pom.xml index 7c3c992079..91a0079611 100644 --- a/akka-persistence/pom.xml +++ b/akka-persistence/pom.xml @@ -17,13 +17,13 @@ akka-util - se.scalablesolutions.akka - 0.6 + ${project.groupId} + ${project.version} akka-actors - se.scalablesolutions.akka - 0.6 + ${project.groupId} + ${project.version} @@ -49,6 +49,20 @@ commons-pool 1.5.1 + + + + org.scalatest + scalatest + 1.0 + test + + + junit + junit + 4.5 + test + diff --git a/akka-rest/pom.xml b/akka-rest/pom.xml index 069b9c6d1a..ab010b9fa9 100644 --- a/akka-rest/pom.xml +++ b/akka-rest/pom.xml @@ -19,13 +19,13 @@ akka-util - se.scalablesolutions.akka - 0.6 + ${project.groupId} + ${project.version} akka-actors - se.scalablesolutions.akka - 0.6 + ${project.groupId} + ${project.version} diff --git a/akka-samples-java/pom.xml b/akka-samples-java/pom.xml index 2a7cf2adff..9eb36bc01d 100644 --- a/akka-samples-java/pom.xml +++ b/akka-samples-java/pom.xml @@ -17,33 +17,33 @@ akka-util-java - se.scalablesolutions.akka - 0.6 + ${project.groupId} + ${project.version} akka-util - se.scalablesolutions.akka - 0.6 + ${project.groupId} + ${project.version} akka-actors - se.scalablesolutions.akka - 0.6 + ${project.groupId} + ${project.version} akka-persistence - se.scalablesolutions.akka - 0.6 + ${project.groupId} + ${project.version} akka-rest - se.scalablesolutions.akka - 0.6 + ${project.groupId} + ${project.version} akka-kernel - se.scalablesolutions.akka - 0.6 + ${project.groupId} + ${project.version} javax.ws.rs @@ -73,8 +73,8 @@ install - + diff --git a/akka-samples-lift/pom.xml b/akka-samples-lift/pom.xml index 20af39b13c..b198f5403a 100644 --- a/akka-samples-lift/pom.xml +++ b/akka-samples-lift/pom.xml @@ -21,33 +21,33 @@ akka-util-java - se.scalablesolutions.akka - 0.6 + ${project.groupId} + ${project.version} akka-util - se.scalablesolutions.akka - 0.6 + ${project.groupId} + ${project.version} akka-actors - se.scalablesolutions.akka - 0.6 + ${project.groupId} + ${project.version} akka-persistence - se.scalablesolutions.akka - 0.6 + ${project.groupId} + ${project.version} akka-rest - se.scalablesolutions.akka - 0.6 + ${project.groupId} + ${project.version} akka-kernel - se.scalablesolutions.akka - 0.6 + ${project.groupId} + ${project.version} javax.ws.rs diff --git a/akka-samples-scala/pom.xml b/akka-samples-scala/pom.xml index 59e9948e3d..9739f3a07b 100644 --- a/akka-samples-scala/pom.xml +++ b/akka-samples-scala/pom.xml @@ -17,33 +17,33 @@ akka-util-java - se.scalablesolutions.akka - 0.6 + ${project.groupId} + ${project.version} akka-util - se.scalablesolutions.akka - 0.6 + ${project.groupId} + ${project.version} akka-actors - se.scalablesolutions.akka - 0.6 + ${project.groupId} + ${project.version} akka-persistence - se.scalablesolutions.akka - 0.6 + ${project.groupId} + ${project.version} akka-rest - se.scalablesolutions.akka - 0.6 + ${project.groupId} + ${project.version} akka-kernel - se.scalablesolutions.akka - 0.6 + ${project.groupId} + ${project.version} javax.ws.rs @@ -62,8 +62,8 @@ install - + diff --git a/akka-samples-security/pom.xml b/akka-samples-security/pom.xml index d870bdac17..e604febf53 100644 --- a/akka-samples-security/pom.xml +++ b/akka-samples-security/pom.xml @@ -17,33 +17,33 @@ akka-kernel - se.scalablesolutions.akka - 0.6 + ${project.groupId} + ${project.version} akka-util-java - se.scalablesolutions.akka - 0.6 + ${project.groupId} + ${project.version} akka-util - se.scalablesolutions.akka - 0.6 + ${project.groupId} + ${project.version} akka-actors - se.scalablesolutions.akka - 0.6 + ${project.groupId} + ${project.version} akka-security - se.scalablesolutions.akka - 0.6 + ${project.groupId} + ${project.version} akka-persistence - se.scalablesolutions.akka - 0.6 + ${project.groupId} + ${project.version} javax.ws.rs @@ -68,8 +68,8 @@ install - + diff --git a/akka-security/pom.xml b/akka-security/pom.xml index 6e90607d1a..8758508fdd 100644 --- a/akka-security/pom.xml +++ b/akka-security/pom.xml @@ -18,32 +18,32 @@ org.scala-lang scala-library - 2.7.5 + ${scala.version} akka-actors - se.scalablesolutions.akka - 0.6 + ${project.groupId} + ${project.version} akka-persistence - se.scalablesolutions.akka - 0.6 + ${project.groupId} + ${project.version} akka-util - se.scalablesolutions.akka - 0.6 + ${project.groupId} + ${project.version} - javax.annotation - jsr250-api - 1.0 + javax.annotation + jsr250-api + 1.0 com.sun.jersey @@ -56,11 +56,11 @@ 1.0 - net.liftweb - lift-util - 1.1-M6 + net.liftweb + lift-util + 1.1-M6 - + org.scalatest @@ -80,8 +80,8 @@ 1.8.0 test - - + + diff --git a/akka-util/pom.xml b/akka-util/pom.xml index b8645bd74d..5a7997a3af 100644 --- a/akka-util/pom.xml +++ b/akka-util/pom.xml @@ -18,12 +18,12 @@ org.scala-lang scala-library - 2.7.5 + ${scala.version} net.lag configgy - 1.3 + 1.4 diff --git a/docs/scaladocs-akka-actors/se/scalablesolutions/akka/nio/RemoteServer$object.html b/docs/scaladocs-akka-actors/se/scalablesolutions/akka/nio/RemoteServer$object.html index 94a5b01949..ca03ada2f5 100644 --- a/docs/scaladocs-akka-actors/se/scalablesolutions/akka/nio/RemoteServer$object.html +++ b/docs/scaladocs-akka-actors/se/scalablesolutions/akka/nio/RemoteServer$object.html @@ -60,7 +60,7 @@

- Source: RemoteServer.scala(25) + Source: RemoteServerNode.scala(25) diff --git a/docs/scaladocs-akka-actors/se/scalablesolutions/akka/nio/RemoteServerHandler.html b/docs/scaladocs-akka-actors/se/scalablesolutions/akka/nio/RemoteServerHandler.html index 4c1fee9478..70071c45c7 100644 --- a/docs/scaladocs-akka-actors/se/scalablesolutions/akka/nio/RemoteServerHandler.html +++ b/docs/scaladocs-akka-actors/se/scalablesolutions/akka/nio/RemoteServerHandler.html @@ -60,7 +60,7 @@

- Source: RemoteServer.scala(86) + Source: RemoteServerNode.scala(86) diff --git a/docs/scaladocs-akka-actors/se/scalablesolutions/akka/nio/RemoteServerPipelineFactory.html b/docs/scaladocs-akka-actors/se/scalablesolutions/akka/nio/RemoteServerPipelineFactory.html index 2709a9bb02..53f1eb9b9d 100644 --- a/docs/scaladocs-akka-actors/se/scalablesolutions/akka/nio/RemoteServerPipelineFactory.html +++ b/docs/scaladocs-akka-actors/se/scalablesolutions/akka/nio/RemoteServerPipelineFactory.html @@ -60,7 +60,7 @@

- Source: RemoteServer.scala(70) + Source: RemoteServerNode.scala(70) diff --git a/pom.xml b/pom.xml index 7361426e9a..7ffd4cd08a 100755 --- a/pom.xml +++ b/pom.xml @@ -9,12 +9,25 @@ se.scalablesolutions.akka 0.6 2009 + http://akkasource.org pom + + Akka implements a unique hybrid of the Actor model and Software Transactional Memory (STM). + Akka gives you you: + * Concurrency (high-level and simple). + * Asynchronous, non-blocking, event-driven and highly performant components. + * Scalability through very performant remote actors. + * Fault-tolerance through supervision hierarchies with “let-it-crash” semantics. + + - 0.6 - se.scalablesolutions.akka - 2.7.5 + 2.7.7 + UTF-8 + 1.5 + ${maven.compiler.source} + ${project.build.sourceEncoding} + ${project.build.sourceEncoding} @@ -39,12 +52,6 @@ http://scalablesolutions.se - - scm:git:git://github.com/jboner/akka.git - scm:git:git@github.com:jboner/akka.git - http://github.com/jboner/akka - - The Apache License, ASL Version 2.0 @@ -66,17 +73,47 @@ + + scm:git:git://github.com/jboner/akka.git + scm:git:git@github.com:jboner/akka.git + http://github.com/jboner/akka + + + + assembla + http://assembla.com/spaces/akka/ + + + + hudson + http://hudson.scala-tools.org/job/akka/ + + + + + + + + + User and Developer Discussion List + http://groups.google.com/group/akka-user + akka-user@googlegroups.com + akka-user+subscribe@googlegroups.com + akka-user+unsubscribe@googlegroups.com + + + - - repo1.maven - Maven Main Repository - http://repo1.maven.org/maven2 - project.embedded.module Project Embedded Repository file://${basedir}/../embedded-repo + + repo1.maven + Maven Main Repository + http://repo1.maven.org/maven2 + scala-tools-snapshots Scala-Tools Maven2 Snapshot Repository @@ -262,7 +299,7 @@ - ${akka.version} + ${project.version} @@ -348,28 +385,58 @@ + org.apache.maven.plugins maven-project-info-reports-plugin + 2.1.2 + + + + cim + dependencies + dependency-convergence + + index + issue-tracking + license + mailing-list + + plugins + project-team + scm + summary + + + org.scala-tools maven-scala-plugin - 2.9.1 + 2.12.2 - - -Xmx1024m - -DpackageLinkDefs=file://${basedir}/../vscaladocs-packageLinkDefs.properties - - - - + ${project.build.sourceEncoding} + 1.2-SNAPSHOT ${scala.version} + + -Xmx1024m + -DpackageLinkDefs=file://${project.build.directory}/packageLinkDefs.properties + + + org.apache.maven.plugins maven-changes-plugin - 2.0-beta-3 + 2.1 From f9c9a66a479c594141e2c2eedad4bff81d3c66fb Mon Sep 17 00:00:00 2001 From: jboner Date: Tue, 24 Nov 2009 22:31:02 +0100 Subject: [PATCH 14/20] removed unused dependencies --- akka-actors/pom.xml | 27 ----------- akka-amqp/pom.xml | 9 +--- akka-kernel/pom.xml | 91 +++++++++++------------------------ akka-samples-lift/pom.xml | 1 + akka-samples-security/pom.xml | 6 +-- 5 files changed, 33 insertions(+), 101 deletions(-) diff --git a/akka-actors/pom.xml b/akka-actors/pom.xml index b3dd417381..73d188f4e9 100644 --- a/akka-actors/pom.xml +++ b/akka-actors/pom.xml @@ -57,11 +57,6 @@ configgy 1.4
- - org.guiceyfruit - guice-core - 2.0-beta-4 - org.jboss.netty netty @@ -115,28 +110,6 @@ 0.2 - - - org.slf4j - slf4j-log4j12 - 1.4.3 - - - org.slf4j - slf4j-api - 1.4.3 - - - log4j - log4j - 1.2.13 - - - commons-logging - commons-logging - 1.0.4 - - org.scalatest diff --git a/akka-amqp/pom.xml b/akka-amqp/pom.xml index 323f90a0e4..113b6917b1 100644 --- a/akka-amqp/pom.xml +++ b/akka-amqp/pom.xml @@ -24,17 +24,12 @@ akka-actors ${project.groupId} ${project.version} - - + + com.rabbitmq rabbitmq-client 0.9.1 - - commons-io - commons-io - 1.4 -
diff --git a/akka-kernel/pom.xml b/akka-kernel/pom.xml index 93fce3f319..c07cf68748 100755 --- a/akka-kernel/pom.xml +++ b/akka-kernel/pom.xml @@ -42,7 +42,7 @@ ${project.groupId} ${project.version}
- + akka-security ${project.groupId} ${project.version} @@ -69,21 +69,11 @@ configgy 1.4 - - org.guiceyfruit - guiceyfruit-core - 2.0 - org.apache.camel camel-core 2.0-SNAPSHOT - - org.guiceyfruit - guice-core - 2.0-beta-4 - org.jboss.netty netty @@ -165,39 +155,12 @@ cassandra 0.4.1 - - com.facebook - thrift - 1.0 - commons-pool commons-pool 1.5.1 - - - org.slf4j - slf4j-log4j12 - 1.4.3 - - - org.slf4j - slf4j-api - 1.4.3 - - - log4j - log4j - 1.2.13 - - - commons-logging - commons-logging - 1.0.4 - - com.sun.grizzly @@ -244,32 +207,32 @@ - org.apache.maven.plugins - maven-shade-plugin - 1.2.1 - - - install - - shade - - - - - junit:junit - - - - - - - se.scalablesolutions.akka.Kernel - - - - - - + org.apache.maven.plugins + maven-shade-plugin + 1.2.1 + + + install + + shade + + + + + junit:junit + + + + + + + se.scalablesolutions.akka.Kernel + + + + + + maven-antrun-plugin diff --git a/akka-samples-lift/pom.xml b/akka-samples-lift/pom.xml index b198f5403a..ef47434b1a 100644 --- a/akka-samples-lift/pom.xml +++ b/akka-samples-lift/pom.xml @@ -75,6 +75,7 @@ 2.5 provided + junit junit diff --git a/akka-samples-security/pom.xml b/akka-samples-security/pom.xml index e604febf53..5a3bd9adb8 100644 --- a/akka-samples-security/pom.xml +++ b/akka-samples-security/pom.xml @@ -51,9 +51,9 @@ 1.0 - javax.annotation - jsr250-api - 1.0 + javax.annotation + jsr250-api + 1.0
From 4dbd3f6afee131dd0ef82932a4c07070025fdb0c Mon Sep 17 00:00:00 2001 From: jboner Date: Wed, 25 Nov 2009 12:42:50 +0100 Subject: [PATCH 15/20] renamed RemoteServerNode -> RemoteNode --- akka-actors/src/main/scala/nio/RemoteServer.scala | 6 +++--- akka-actors/src/test/scala/RemoteActorTest.scala | 5 +++-- akka-actors/src/test/scala/RemoteSupervisorTest.scala | 4 ++-- .../scalablesolutions/akka/api/RemoteInMemoryStateTest.java | 4 ++-- akka-kernel/src/main/scala/Kernel.scala | 4 ++-- 5 files changed, 12 insertions(+), 11 deletions(-) diff --git a/akka-actors/src/main/scala/nio/RemoteServer.scala b/akka-actors/src/main/scala/nio/RemoteServer.scala index 2ffe0e1f1a..5a542268c8 100755 --- a/akka-actors/src/main/scala/nio/RemoteServer.scala +++ b/akka-actors/src/main/scala/nio/RemoteServer.scala @@ -24,7 +24,7 @@ import org.jboss.netty.handler.codec.compression.{ZlibEncoder, ZlibDecoder} * Use this object if you need a single remote server on a specific node. * *
- * RemoteServerNode.start
+ * RemoteNode.start
  * 
* * If you need to create more than one, then you can use the RemoteServer: @@ -36,7 +36,7 @@ import org.jboss.netty.handler.codec.compression.{ZlibEncoder, ZlibDecoder} * * @author Jonas Bonér */ -object RemoteServerNode extends RemoteServer +object RemoteNode extends RemoteServer /** * This object holds configuration variables. @@ -69,7 +69,7 @@ object RemoteServer { * If you need to create more than one, then you can use the RemoteServer: * *
- * RemoteServerNode.start
+ * RemoteNode.start
  * 
* * @author Jonas Bonér diff --git a/akka-actors/src/test/scala/RemoteActorTest.scala b/akka-actors/src/test/scala/RemoteActorTest.scala index f0ab401eac..3e614bd42c 100644 --- a/akka-actors/src/test/scala/RemoteActorTest.scala +++ b/akka-actors/src/test/scala/RemoteActorTest.scala @@ -5,7 +5,8 @@ import junit.framework.TestCase import org.scalatest.junit.JUnitSuite import org.junit.Test -import se.scalablesolutions.akka.nio.{RemoteServerNode, RemoteServer, RemoteClient} + +import se.scalablesolutions.akka.nio.{RemoteNode, RemoteServer, RemoteClient} object Global { var oneWay = "nada" @@ -32,7 +33,7 @@ class RemoteActorTest extends JUnitSuite { akka.Config.config new Thread(new Runnable() { def run = { - RemoteServerNode.start + RemoteNode.start } }).start Thread.sleep(1000) diff --git a/akka-actors/src/test/scala/RemoteSupervisorTest.scala b/akka-actors/src/test/scala/RemoteSupervisorTest.scala index 42a8837db3..0fef2a2e6e 100644 --- a/akka-actors/src/test/scala/RemoteSupervisorTest.scala +++ b/akka-actors/src/test/scala/RemoteSupervisorTest.scala @@ -6,10 +6,10 @@ package se.scalablesolutions.akka.actor import se.scalablesolutions.akka.serialization.BinaryString import se.scalablesolutions.akka.config.ScalaConfig._ +import se.scalablesolutions.akka.nio.{RemoteNode, RemoteClient, RemoteServer} import org.scalatest.junit.JUnitSuite import org.junit.Test -import se.scalablesolutions.akka.nio.{RemoteServerNode, RemoteClient, RemoteServer} object Log { var messageLog: String = "" @@ -25,7 +25,7 @@ class RemoteSupervisorTest extends JUnitSuite { akka.Config.config new Thread(new Runnable() { def run = { - RemoteServerNode.start + RemoteNode.start } }).start Thread.sleep(1000) diff --git a/akka-fun-test-java/src/test/java/se/scalablesolutions/akka/api/RemoteInMemoryStateTest.java b/akka-fun-test-java/src/test/java/se/scalablesolutions/akka/api/RemoteInMemoryStateTest.java index 3703efb43a..de2c1dbd41 100644 --- a/akka-fun-test-java/src/test/java/se/scalablesolutions/akka/api/RemoteInMemoryStateTest.java +++ b/akka-fun-test-java/src/test/java/se/scalablesolutions/akka/api/RemoteInMemoryStateTest.java @@ -7,7 +7,7 @@ package se.scalablesolutions.akka.api; import se.scalablesolutions.akka.Config; import se.scalablesolutions.akka.actor.ActiveObject; import se.scalablesolutions.akka.config.ActiveObjectConfigurator; -import se.scalablesolutions.akka.nio.RemoteServerNode; +import se.scalablesolutions.akka.nio.RemoteNode; import junit.framework.TestCase; @@ -17,7 +17,7 @@ public class RemoteInMemoryStateTest extends TestCase { static { new Thread(new Runnable() { public void run() { - RemoteServerNode.start(); + RemoteNode.start(); } }).start(); try { Thread.currentThread().sleep(1000); } catch (Exception e) {} diff --git a/akka-kernel/src/main/scala/Kernel.scala b/akka-kernel/src/main/scala/Kernel.scala index 295a1d3b38..8514198bc1 100644 --- a/akka-kernel/src/main/scala/Kernel.scala +++ b/akka-kernel/src/main/scala/Kernel.scala @@ -12,7 +12,7 @@ import javax.ws.rs.core.UriBuilder import java.io.File import java.net.URLClassLoader -import se.scalablesolutions.akka.nio.RemoteServerNode +import se.scalablesolutions.akka.nio.RemoteNode import se.scalablesolutions.akka.util.Logging /** @@ -54,7 +54,7 @@ object Kernel extends Logging { def startRemoteService = { // FIXME manage remote serve thread for graceful shutdown val remoteServerThread = new Thread(new Runnable() { - def run = RemoteServerNode.start(applicationLoader) + def run = RemoteNode.start(applicationLoader) }, "Akka Remote Service") remoteServerThread.start } From 1b21fe6e1b13964dc5118f52a0d7a2d8e96c338b Mon Sep 17 00:00:00 2001 From: jboner Date: Wed, 25 Nov 2009 14:51:05 +0100 Subject: [PATCH 16/20] Addded reference count for dispatcher to allow shutdown and GC of event-driven actors using the global event-driven dispatcher --- akka-actors/src/main/scala/actor/Actor.scala | 3 +-- akka-actors/src/main/scala/dispatch/Dispatchers.scala | 2 +- .../src/main/scala/dispatch/MessageDispatcherBase.scala | 4 ++++ akka-actors/src/main/scala/dispatch/Reactor.scala | 1 + .../src/main/scala/dispatch/ThreadBasedDispatcher.scala | 2 ++ 5 files changed, 9 insertions(+), 3 deletions(-) diff --git a/akka-actors/src/main/scala/actor/Actor.scala b/akka-actors/src/main/scala/actor/Actor.scala index 6fa50ea106..9430fb2127 100644 --- a/akka-actors/src/main/scala/actor/Actor.scala +++ b/akka-actors/src/main/scala/actor/Actor.scala @@ -398,8 +398,7 @@ trait Actor extends Logging with TransactionManagement { def stop = synchronized { if (_isRunning) { messageDispatcher.unregisterHandler(this) - if (messageDispatcher.isInstanceOf[ThreadBasedDispatcher]) messageDispatcher.shutdown - // FIXME: Need to do reference count to know if EventBasedThreadPoolDispatcher and EventBasedSingleThreadDispatcher can be shut down + if (messageDispatcher.canBeShutDown) messageDispatcher.shutdown // shut down in the dispatcher's references is zero _isRunning = false _isShutDown = true shutdown diff --git a/akka-actors/src/main/scala/dispatch/Dispatchers.scala b/akka-actors/src/main/scala/dispatch/Dispatchers.scala index a82191af1a..1209efe5c8 100644 --- a/akka-actors/src/main/scala/dispatch/Dispatchers.scala +++ b/akka-actors/src/main/scala/dispatch/Dispatchers.scala @@ -41,7 +41,7 @@ import se.scalablesolutions.akka.actor.Actor object Dispatchers { object globalEventBasedThreadPoolDispatcher extends EventBasedThreadPoolDispatcher("global:eventbased:dispatcher") - + /** * Creates an event based dispatcher serving multiple (millions) of actors through a thread pool. * Has a fluent builder interface for configuring its semantics. diff --git a/akka-actors/src/main/scala/dispatch/MessageDispatcherBase.scala b/akka-actors/src/main/scala/dispatch/MessageDispatcherBase.scala index 4516dcda6e..52fe26601b 100644 --- a/akka-actors/src/main/scala/dispatch/MessageDispatcherBase.scala +++ b/akka-actors/src/main/scala/dispatch/MessageDispatcherBase.scala @@ -29,6 +29,10 @@ abstract class MessageDispatcherBase(val name: String) extends MessageDispatcher messageHandlers.remove(key) } + def canBeShutDown: Boolean = guard.synchronized { + messageHandlers.isEmpty + } + def shutdown = if (active) { active = false selectorThread.interrupt diff --git a/akka-actors/src/main/scala/dispatch/Reactor.scala b/akka-actors/src/main/scala/dispatch/Reactor.scala index 38c311097d..36a1dfb989 100644 --- a/akka-actors/src/main/scala/dispatch/Reactor.scala +++ b/akka-actors/src/main/scala/dispatch/Reactor.scala @@ -25,6 +25,7 @@ trait MessageDispatcher { def messageQueue: MessageQueue def registerHandler(key: AnyRef, handler: MessageInvoker) def unregisterHandler(key: AnyRef) + def canBeShutDown: Boolean def start def shutdown } diff --git a/akka-actors/src/main/scala/dispatch/ThreadBasedDispatcher.scala b/akka-actors/src/main/scala/dispatch/ThreadBasedDispatcher.scala index a8fc5ada6b..86c7e0ed09 100644 --- a/akka-actors/src/main/scala/dispatch/ThreadBasedDispatcher.scala +++ b/akka-actors/src/main/scala/dispatch/ThreadBasedDispatcher.scala @@ -39,6 +39,8 @@ class ThreadBasedDispatcher private[akka] (val name: String, val messageHandler: selectorThread.start } + def canBeShutDown = true + def shutdown = if (active) { active = false selectorThread.interrupt From 793741d1f11e977859e0a52c3e05304a926289b0 Mon Sep 17 00:00:00 2001 From: debasishg Date: Wed, 25 Nov 2009 23:39:06 +0530 Subject: [PATCH 17/20] fixed MongoDB tests and fixed bug in transaction handling with PersistentMap --- .../src/main/scala/MongoStorage.scala | 9 ++- .../src/main/scala/PersistentState.scala | 11 ++-- .../test/scala/MongoPersistentActorSpec.scala | 57 +++++++++---------- .../src/test/scala/MongoStorageSpec.scala | 10 ++++ 4 files changed, 51 insertions(+), 36 deletions(-) diff --git a/akka-persistence/src/main/scala/MongoStorage.scala b/akka-persistence/src/main/scala/MongoStorage.scala index f9f566c92f..8fd7a0c4b5 100644 --- a/akka-persistence/src/main/scala/MongoStorage.scala +++ b/akka-persistence/src/main/scala/MongoStorage.scala @@ -90,7 +90,12 @@ object MongoStorage extends MapStorage with VectorStorage with RefStorage with L case None => case Some(dbo) => { val orig = dbo.get(VALUE).asInstanceOf[DBObject].toMap - orig.remove(key.asInstanceOf[String]) + if (key.isInstanceOf[List[_]]) { + val keys = key.asInstanceOf[List[_]] + keys.foreach(k => orig.remove(k.asInstanceOf[String])) + } else { + orig.remove(key.asInstanceOf[String]) + } // remove existing reference removeMapStorageFor(name) @@ -287,4 +292,4 @@ object MongoStorage extends MapStorage with VectorStorage with RefStorage with L Some(serializer.in[AnyRef](dbo.get(VALUE).asInstanceOf[Array[Byte]])) } } -} \ No newline at end of file +} diff --git a/akka-persistence/src/main/scala/PersistentState.scala b/akka-persistence/src/main/scala/PersistentState.scala index f659c00f14..3a63ea16f9 100644 --- a/akka-persistence/src/main/scala/PersistentState.scala +++ b/akka-persistence/src/main/scala/PersistentState.scala @@ -4,6 +4,7 @@ package se.scalablesolutions.akka.state +import util.Logging import se.scalablesolutions.akka.stm.TransactionManagement.currentTransaction import se.scalablesolutions.akka.collection._ @@ -59,9 +60,9 @@ object PersistentState { * * @author Jonas Bonér */ -trait PersistentMap extends scala.collection.mutable.Map[AnyRef, AnyRef] with Transactional with Committable { +trait PersistentMap extends scala.collection.mutable.Map[AnyRef, AnyRef] with Transactional with Committable with Logging { protected val newAndUpdatedEntries = TransactionalState.newMap[AnyRef, AnyRef] - protected val removedEntries = TransactionalState.newMap[AnyRef, AnyRef] + protected val removedEntries = TransactionalState.newVector[AnyRef] protected val shouldClearOnCommit = TransactionalRef[Boolean]() // to be concretized in subclasses @@ -91,7 +92,7 @@ trait PersistentMap extends scala.collection.mutable.Map[AnyRef, AnyRef] with Tr def remove(key: AnyRef) = { register - removedEntries.remove(key) + removedEntries.add(key) } def slice(start: Option[AnyRef], count: Int): List[Tuple2[AnyRef, AnyRef]] = slice(start, None, count) @@ -114,7 +115,9 @@ trait PersistentMap extends scala.collection.mutable.Map[AnyRef, AnyRef] with Tr } catch { case e: Exception => 0 } override def get(key: AnyRef): Option[AnyRef] = { - if (newAndUpdatedEntries.contains(key)) newAndUpdatedEntries.get(key) + if (newAndUpdatedEntries.contains(key)) { + newAndUpdatedEntries.get(key) + } else try { storage.getMapStorageEntryFor(uuid, key) } catch { case e: Exception => None } diff --git a/akka-persistence/src/test/scala/MongoPersistentActorSpec.scala b/akka-persistence/src/test/scala/MongoPersistentActorSpec.scala index 67b116863f..10bf943dbb 100644 --- a/akka-persistence/src/test/scala/MongoPersistentActorSpec.scala +++ b/akka-persistence/src/test/scala/MongoPersistentActorSpec.scala @@ -45,13 +45,12 @@ class BankAccountActor extends Actor { // debit amount: can fail case Debit(accountNo, amount, failer) => txnLog.add("Debit:" + accountNo + " " + amount) + val m: BigInt = accountState.get(accountNo) match { + case Some(JsNumber(n)) => + BigInt(n.asInstanceOf[BigDecimal].intValue) case None => 0 - case Some(v) => { - val JsNumber(n) = v.asInstanceOf[JsValue] - BigInt(n.toString) - } } accountState.put(accountNo, (m - amount)) if (amount > m) @@ -62,10 +61,11 @@ class BankAccountActor extends Actor { // demonstrates true rollback even if multiple puts have been done case MultiDebit(accountNo, amounts, failer) => txnLog.add("MultiDebit:" + accountNo + " " + amounts.map(_.intValue).foldLeft(0)(_ + _)) + val m: BigInt = accountState.get(accountNo) match { + case Some(JsNumber(n)) => BigInt(n.toString) case None => 0 - case Some(v) => BigInt(v.asInstanceOf[String]) } var bal: BigInt = 0 amounts.foreach {amount => @@ -78,13 +78,12 @@ class BankAccountActor extends Actor { // credit amount case Credit(accountNo, amount) => txnLog.add("Credit:" + accountNo + " " + amount) + val m: BigInt = accountState.get(accountNo) match { + case Some(JsNumber(n)) => + BigInt(n.asInstanceOf[BigDecimal].intValue) case None => 0 - case Some(v) => { - val JsNumber(n) = v.asInstanceOf[JsValue] - BigInt(n.toString) - } } accountState.put(accountNo, (m + amount)) reply(m + amount) @@ -103,19 +102,20 @@ class MongoPersistentActorSpec extends TestCase { failer.start bactor !! Credit("a-123", 5000) bactor !! Debit("a-123", 3000, failer) - val b = (bactor !! Balance("a-123")).get.asInstanceOf[JsValue] - val JsNumber(n) = b - assertEquals(BigInt(2000), BigInt(n.toString)) + + val JsNumber(b) = (bactor !! Balance("a-123")).get.asInstanceOf[JsValue] + assertEquals(BigInt(2000), BigInt(b.intValue)) bactor !! Credit("a-123", 7000) - val b1 = (bactor !! Balance("a-123")).get.asInstanceOf[JsValue] - val JsNumber(n1) = b1 - assertEquals(BigInt(9000), BigInt(n1.toString)) + + val JsNumber(b1) = (bactor !! Balance("a-123")).get.asInstanceOf[JsValue] + assertEquals(BigInt(9000), BigInt(b1.intValue)) bactor !! Debit("a-123", 8000, failer) - val b2 = (bactor !! Balance("a-123")).get.asInstanceOf[JsValue] - val JsNumber(n2) = b2 - assertEquals(BigInt(1000), BigInt(n2.toString)) + + val JsNumber(b2) = (bactor !! Balance("a-123")).get.asInstanceOf[JsValue] + assertEquals(BigInt(1000), BigInt(b2.intValue)) + assertEquals(7, (bactor !! LogSize).get) } @@ -125,9 +125,8 @@ class MongoPersistentActorSpec extends TestCase { bactor.start bactor !! Credit("a-123", 5000) - val b = (bactor !! Balance("a-123")).get.asInstanceOf[JsValue] - val JsNumber(n) = b - assertEquals(BigInt(5000), BigInt(n.toString)) + val JsNumber(b) = (bactor !! Balance("a-123")).get.asInstanceOf[JsValue] + assertEquals(BigInt(5000), BigInt(b.intValue)) val failer = new PersistentFailerActor failer.start @@ -136,9 +135,8 @@ class MongoPersistentActorSpec extends TestCase { fail("should throw exception") } catch { case e: RuntimeException => {}} - val b1 = (bactor !! Balance("a-123")).get.asInstanceOf[JsValue] - val JsNumber(n1) = b1 - assertEquals(BigInt(5000), BigInt(n1.toString)) + val JsNumber(b1) = (bactor !! Balance("a-123")).get.asInstanceOf[JsValue] + assertEquals(BigInt(5000), BigInt(b1.intValue)) // should not count the failed one assertEquals(3, (bactor !! LogSize).get) @@ -149,9 +147,9 @@ class MongoPersistentActorSpec extends TestCase { val bactor = new BankAccountActor bactor.start bactor !! Credit("a-123", 5000) - val b = (bactor !! Balance("a-123")).get.asInstanceOf[JsValue] - val JsNumber(n) = b - assertEquals(BigInt(5000), BigInt(n.toString)) + + val JsNumber(b) = (bactor !! Balance("a-123")).get.asInstanceOf[JsValue] + assertEquals(BigInt(5000), BigInt(b.intValue)) val failer = new PersistentFailerActor failer.start @@ -160,9 +158,8 @@ class MongoPersistentActorSpec extends TestCase { fail("should throw exception") } catch { case e: RuntimeException => {}} - val b1 = (bactor !! Balance("a-123")).get.asInstanceOf[JsValue] - val JsNumber(n1) = b1 - assertEquals(BigInt(5000), BigInt(n1.toString)) + val JsNumber(b1) = (bactor !! Balance("a-123")).get.asInstanceOf[JsValue] + assertEquals(BigInt(5000), BigInt(b1.intValue)) // should not count the failed one assertEquals(3, (bactor !! LogSize).get) diff --git a/akka-persistence/src/test/scala/MongoStorageSpec.scala b/akka-persistence/src/test/scala/MongoStorageSpec.scala index 89971a6c25..4adf61ced2 100644 --- a/akka-persistence/src/test/scala/MongoStorageSpec.scala +++ b/akka-persistence/src/test/scala/MongoStorageSpec.scala @@ -272,6 +272,16 @@ class MongoStorageSpec extends TestCase { fail("should throw exception") } catch { case e => {}} + // remove key "4" + MongoStorage.removeMapStorageFor("U-M1", "4") + assertEquals(3, + MongoStorage.getMapStorageSizeFor("U-M1")) + + // remove key "2" + MongoStorage.removeMapStorageFor("U-M1", "2") + assertEquals(2, + MongoStorage.getMapStorageSizeFor("U-M1")) + // remove the whole stuff MongoStorage.removeMapStorageFor("U-M1") From 8174225892177ed89c93fe6650c7ffb1f5813b59 Mon Sep 17 00:00:00 2001 From: jboner Date: Wed, 25 Nov 2009 20:37:00 +0100 Subject: [PATCH 18/20] Upgraded to latest Mulitverse SNAPSHOT --- akka-actors/src/main/scala/actor/Actor.scala | 2 +- .../src/main/scala/stm/Transaction.scala | 2 +- .../scala/stm/TransactionManagement.scala | 2 +- .../main/scala/stm/TransactionalState.scala | 2 +- .../akka/stm/AtomicTemplate.java | 19 ++++++++++++------- 5 files changed, 16 insertions(+), 11 deletions(-) diff --git a/akka-actors/src/main/scala/actor/Actor.scala b/akka-actors/src/main/scala/actor/Actor.scala index 9430fb2127..86e3c1c988 100644 --- a/akka-actors/src/main/scala/actor/Actor.scala +++ b/akka-actors/src/main/scala/actor/Actor.scala @@ -21,7 +21,7 @@ import se.scalablesolutions.akka.util.Logging import org.codehaus.aspectwerkz.proxy.Uuid -import org.multiverse.utils.ThreadLocalTransaction._ +import org.multiverse.api.ThreadLocalTransaction._ /** * Mix in this trait to give an actor TransactionRequired semantics. diff --git a/akka-actors/src/main/scala/stm/Transaction.scala b/akka-actors/src/main/scala/stm/Transaction.scala index 20ea9ede9f..14c5b0d106 100644 --- a/akka-actors/src/main/scala/stm/Transaction.scala +++ b/akka-actors/src/main/scala/stm/Transaction.scala @@ -12,7 +12,7 @@ import se.scalablesolutions.akka.util.Logging import org.multiverse.api.{Stm, Transaction => MultiverseTransaction} import org.multiverse.api.GlobalStmInstance.getGlobalStmInstance -import org.multiverse.utils.ThreadLocalTransaction._ +import org.multiverse.api.ThreadLocalTransaction._ import org.multiverse.templates.OrElseTemplate import scala.collection.mutable.HashMap diff --git a/akka-actors/src/main/scala/stm/TransactionManagement.scala b/akka-actors/src/main/scala/stm/TransactionManagement.scala index 06e65d0ceb..6a3ee9abf8 100644 --- a/akka-actors/src/main/scala/stm/TransactionManagement.scala +++ b/akka-actors/src/main/scala/stm/TransactionManagement.scala @@ -10,7 +10,7 @@ import se.scalablesolutions.akka.util.Logging import scala.collection.mutable.HashSet -import org.multiverse.utils.ThreadLocalTransaction._ +import org.multiverse.api.ThreadLocalTransaction._ class StmException(msg: String) extends RuntimeException(msg) diff --git a/akka-actors/src/main/scala/stm/TransactionalState.scala b/akka-actors/src/main/scala/stm/TransactionalState.scala index de3b97e794..bd89a41224 100644 --- a/akka-actors/src/main/scala/stm/TransactionalState.scala +++ b/akka-actors/src/main/scala/stm/TransactionalState.scala @@ -74,7 +74,7 @@ object TransactionalRef { * @author Jonas Bonér */ class TransactionalRef[T] extends Transactional { - import org.multiverse.utils.ThreadLocalTransaction._ + import org.multiverse.api.ThreadLocalTransaction._ private[this] val ref: Ref[T] = atomic { new Ref } diff --git a/akka-util-java/src/main/java/se/scalablesolutions/akka/stm/AtomicTemplate.java b/akka-util-java/src/main/java/se/scalablesolutions/akka/stm/AtomicTemplate.java index d01d1c12a4..a693ff1248 100644 --- a/akka-util-java/src/main/java/se/scalablesolutions/akka/stm/AtomicTemplate.java +++ b/akka-util-java/src/main/java/se/scalablesolutions/akka/stm/AtomicTemplate.java @@ -1,16 +1,18 @@ package se.scalablesolutions.akka.stm; -import org.multiverse.templates.AbortedException; +import static org.multiverse.api.GlobalStmInstance.getGlobalStmInstance; import org.multiverse.api.Stm; +import static org.multiverse.api.ThreadLocalTransaction.getThreadLocalTransaction; +import static org.multiverse.api.ThreadLocalTransaction.setThreadLocalTransaction; import org.multiverse.api.Transaction; import org.multiverse.api.TransactionStatus; import org.multiverse.api.exceptions.CommitFailureException; import org.multiverse.api.exceptions.LoadException; import org.multiverse.api.exceptions.RetryError; import org.multiverse.api.exceptions.TooManyRetriesException; -import static org.multiverse.api.GlobalStmInstance.getGlobalStmInstance; -import static org.multiverse.utils.ThreadLocalTransaction.getThreadLocalTransaction; -import static org.multiverse.utils.ThreadLocalTransaction.setThreadLocalTransaction; +import org.multiverse.templates.AbortedException; +import org.multiverse.utils.latches.CheapLatch; +import org.multiverse.utils.latches.Latch; import static java.lang.String.format; import java.util.logging.Logger; @@ -259,7 +261,9 @@ public abstract class AtomicTemplate { postCommit(); return result; } catch (RetryError e) { - t.abortAndWaitForRetry(); + Latch latch = new CheapLatch(); + t.abortAndRegisterRetryLatch(latch); + latch.awaitUninterruptible(); //since the abort is already done, no need to do it again. abort = false; } catch (CommitFailureException ex) { @@ -274,7 +278,8 @@ public abstract class AtomicTemplate { if (abort) { t.abort(); if (reset) { - t.restart(); + t = t.abortAndReturnRestarted(); + setTransaction(t); } } } @@ -333,4 +338,4 @@ public abstract class AtomicTemplate { return (Exception) super.getCause(); } } -} \ No newline at end of file +} From 9c9490ba4190196bdcc13f558d459be8a2fe5882 Mon Sep 17 00:00:00 2001 From: jboner Date: Thu, 26 Nov 2009 16:52:33 +0100 Subject: [PATCH 19/20] improved anonymous actor and atomic block syntax --- akka-actors/pom.xml | 2 +- akka-actors/src/main/scala/actor/Actor.scala | 56 +++++++++++++++---- .../src/main/scala/stm/Transaction.scala | 34 ++++++++--- 3 files changed, 72 insertions(+), 20 deletions(-) diff --git a/akka-actors/pom.xml b/akka-actors/pom.xml index 73d188f4e9..b7372a1e6e 100644 --- a/akka-actors/pom.xml +++ b/akka-actors/pom.xml @@ -4,7 +4,7 @@ 4.0.0 akka-actors - Akka Actors Module + Akka Actors and STM Module jar diff --git a/akka-actors/src/main/scala/actor/Actor.scala b/akka-actors/src/main/scala/actor/Actor.scala index 86e3c1c988..85d39a97d7 100644 --- a/akka-actors/src/main/scala/actor/Actor.scala +++ b/akka-actors/src/main/scala/actor/Actor.scala @@ -66,7 +66,7 @@ class ActorMessageInvoker(val actor: Actor) extends MessageInvoker { /** * @author Jonas Bonér */ -object Actor { +object Actor { val TIMEOUT = config.getInt("akka.actor.timeout", 5000) val SERIALIZE_MESSAGES = config.getBool("akka.actor.serialize-messages", false) @@ -109,15 +109,45 @@ object Actor { * * val a = actor { * ... // init stuff - * } { + * } receive { * case msg => ... // handle message * } *
+ * */ - def actor(body: => Unit)(matcher: PartialFunction[Any, Unit]): Actor = new Actor() { + def actor[A](body: => Unit) = { + def handler[A](body: Unit) = new { + def receive(handler: PartialFunction[Any, Unit]) = new Actor() { + start + body + def receive = handler + } + } + handler(body) + } + + /** + * Use to create an anonymous event-driven actor with a body but no message loop block. + *

+ * This actor can not respond to any messages but can be used as a simple way to + * spawn a lightweight thread to process some task. + *

+ * The actor is started when created. + * Example: + *

+  * import Actor._
+  *
+  * spawn {
+  *   ... // do stuff
+  * }
+  * 
+ */ + def spawn(body: => Unit): Actor = new Actor() { start body - def receive = matcher + def receive = { + case _ => throw new IllegalArgumentException("Actors created with 'actor(body: => Unit)' do not respond to messages.") + } } /** @@ -148,16 +178,22 @@ object Actor { * * val a = actor(LifeCycle(Temporary)) { * ... // init stuff - * } { + * } receive { * case msg => ... // handle message * } *
*/ - def actor(lifeCycleConfig: LifeCycle)(body: => Unit)(matcher: PartialFunction[Any, Unit]): Actor = new Actor() { - start - body - def receive = matcher - } + def actor[A](lifeCycleConfig: LifeCycle)(body: => Unit) = { + def handler[A](body: Unit) = new { + def receive(handler: PartialFunction[Any, Unit]) = new Actor() { + lifeCycle = lifeCycleConfig + start + body + def receive = handler + } + } + handler(body) + } } /** diff --git a/akka-actors/src/main/scala/stm/Transaction.scala b/akka-actors/src/main/scala/stm/Transaction.scala index 14c5b0d106..4fd6d2c83c 100644 --- a/akka-actors/src/main/scala/stm/Transaction.scala +++ b/akka-actors/src/main/scala/stm/Transaction.scala @@ -21,25 +21,37 @@ class NoTransactionInScopeException extends RuntimeException class TransactionRetryException(message: String) extends RuntimeException(message) /** - * Example of atomic transaction management using high-order functions: + * Example of atomic transaction management using the atomic block: *
  * import se.scalablesolutions.akka.stm.Transaction._
+ * 
  * atomic {
  *   .. // do something within a transaction
  * }
  * 
* - * Example of Run-OrElse transaction management. + * Example of atomic transaction management using atomic block with retry count: *
  * import se.scalablesolutions.akka.stm.Transaction._
- * run {
+ * 
+ * atomic(maxNrOfRetries) {
+ *   .. // do something within a transaction
+ * }
+ * 
+ * + * Example of atomically-orElse transaction management. + * Which is a good way to reduce contention and transaction collisions. + *
+ * import se.scalablesolutions.akka.stm.Transaction._
+ * 
+ * atomically {
  *   .. // try to do something
  * } orElse {
  *   .. // if transaction clashes try do do something else to minimize contention
  * }
  * 
* - * Example of atomic transaction management using for comprehensions (monadic usage): + * Example of atomic transaction management using for comprehensions (monadic): * *
  * import se.scalablesolutions.akka.stm.Transaction._
@@ -52,7 +64,7 @@ class TransactionRetryException(message: String) extends RuntimeException(messag
  * }
  * 
* - * Example of using Transaction and TransactionalRef in for comprehensions (monadic usage): + * Example of using Transaction and TransactionalRef in for comprehensions (monadic): * *
  * // For example, if you have a List with TransactionalRef
@@ -87,7 +99,11 @@ object Transaction extends TransactionManagement {
   def foreach(f: Transaction => Unit): Unit = atomic { f(getTransactionInScope) }
 
   // -- atomic block --------------------------
-  private[akka] def atomically[T](body: => T): T = new AtomicTemplate[T](
+  /**
+   * Creates a "pure" STM atomic transaction and by-passes all transactions hooks such as persistence etc.
+   * Only for internal usage.
+   */
+  private[akka] def pureAtomic[T](body: => T): T = new AtomicTemplate[T](
     getGlobalStmInstance, "akka", false, false, TransactionManagement.MAX_NR_OF_RETRIES) {
     def execute(mtx: MultiverseTransaction): T = body
   }.execute()
@@ -151,8 +167,8 @@ object Transaction extends TransactionManagement {
     }.execute
   }
 
-  // -- Run-OrElse --------------------------
-  def run[A](orBody: => A) = elseBody(orBody)
+  // -- atomically-orElse --------------------------
+  def atomically[A](orBody: => A) = elseBody(orBody)
   def elseBody[A](orBody: => A) = new {
     def orElse(elseBody: => A) = new OrElseTemplate[A] {
       def run(t: MultiverseTransaction) = orBody
@@ -176,7 +192,7 @@ object Transaction extends TransactionManagement {
   // --- public methods ---------
 
   def commit = synchronized {
-    atomically {
+    pureAtomic {
       persistentStateMap.values.foreach(_.commit)
       TransactionManagement.clearTransaction
     }

From 4ad156dd13ab7bcfd83755ddf8560d13b5c7267a Mon Sep 17 00:00:00 2001
From: jboner 
Date: Thu, 26 Nov 2009 20:37:49 +0100
Subject: [PATCH 20/20] shaped up scaladoc for transaction

---
 .../src/main/scala/stm/Transaction.scala      | 42 +++++++++++++++----
 1 file changed, 34 insertions(+), 8 deletions(-)

diff --git a/akka-actors/src/main/scala/stm/Transaction.scala b/akka-actors/src/main/scala/stm/Transaction.scala
index 4fd6d2c83c..d34661c37a 100644
--- a/akka-actors/src/main/scala/stm/Transaction.scala
+++ b/akka-actors/src/main/scala/stm/Transaction.scala
@@ -91,14 +91,21 @@ class TransactionRetryException(message: String) extends RuntimeException(messag
 object Transaction extends TransactionManagement {
   val idFactory = new AtomicLong(-1L)
 
-  // -- monadic api --------------------------
+  /**
+   * See ScalaDoc on class.
+   */
   def map[T](f: Transaction => T): T = atomic { f(getTransactionInScope) }
 
+  /**
+   * See ScalaDoc on class.
+   */
   def flatMap[T](f: Transaction => T): T = atomic { f(getTransactionInScope) }
 
+  /**
+   * See ScalaDoc on class.
+   */
   def foreach(f: Transaction => Unit): Unit = atomic { f(getTransactionInScope) }
 
-  // -- atomic block --------------------------
   /**
    * Creates a "pure" STM atomic transaction and by-passes all transactions hooks such as persistence etc.
    * Only for internal usage.
@@ -108,6 +115,9 @@ object Transaction extends TransactionManagement {
     def execute(mtx: MultiverseTransaction): T = body
   }.execute()
 
+  /**
+   * See ScalaDoc on class.
+   */
   def atomic[T](body: => T): T = new AtomicTemplate[T](
     getGlobalStmInstance, "akka", false, false, TransactionManagement.MAX_NR_OF_RETRIES) {
     def execute(mtx: MultiverseTransaction): T = body
@@ -122,6 +132,9 @@ object Transaction extends TransactionManagement {
     }
   }.execute()
 
+  /**
+   * See ScalaDoc on class.
+   */
   def atomic[T](retryCount: Int)(body: => T): T = {
     new AtomicTemplate[T](getGlobalStmInstance, "akka", false, false, retryCount) {
       def execute(mtx: MultiverseTransaction): T = body
@@ -137,6 +150,9 @@ object Transaction extends TransactionManagement {
     }.execute
   }
 
+  /**
+   * See ScalaDoc on class.
+   */
   def atomicReadOnly[T](retryCount: Int)(body: => T): T = {
     new AtomicTemplate[T](getGlobalStmInstance, "akka", false, true, retryCount) {
       def execute(mtx: MultiverseTransaction): T = body
@@ -152,6 +168,9 @@ object Transaction extends TransactionManagement {
     }.execute
   }
 
+  /**
+   * See ScalaDoc on class.
+   */
   def atomicReadOnly[T](body: => T): T = {
     new AtomicTemplate[T](true) {
       def execute(mtx: MultiverseTransaction): T = body
@@ -167,12 +186,19 @@ object Transaction extends TransactionManagement {
     }.execute
   }
 
-  // -- atomically-orElse --------------------------
-  def atomically[A](orBody: => A) = elseBody(orBody)
-  def elseBody[A](orBody: => A) = new {
-    def orElse(elseBody: => A) = new OrElseTemplate[A] {
-      def run(t: MultiverseTransaction) = orBody
-      def orelserun(t: MultiverseTransaction) = elseBody
+  /**
+   * See ScalaDoc on class.
+   */
+  def atomically[A](firstBody: => A) = elseBody(firstBody)
+
+  /**
+   * Should only be used together with atomically to form atomically-orElse constructs.
+   * See ScalaDoc on class.
+   */
+  def elseBody[A](firstBody: => A) = new {
+    def orElse(secondBody: => A) = new OrElseTemplate[A] {
+      def run(t: MultiverseTransaction) = firstBody
+      def orelserun(t: MultiverseTransaction) = secondBody
     }.execute()
   }
 }