Date: Fri, 24 Sep 2010 18:11:29 +0200
Subject: [PATCH 14/82] API-docs improvements.
---
.../main/scala/CamelContextLifecycle.scala | 18 +++---
akka-camel/src/main/scala/CamelService.scala | 38 +++++++-----
akka-camel/src/main/scala/Consumer.scala | 28 ++++-----
.../src/main/scala/ConsumerPublisher.scala | 38 ++++++------
akka-camel/src/main/scala/Message.scala | 6 +-
akka-camel/src/main/scala/Producer.scala | 58 ++++++++++---------
.../main/scala/component/ActorComponent.scala | 44 +++++++++-----
.../scala/component/TypedActorComponent.scala | 19 +++---
8 files changed, 135 insertions(+), 114 deletions(-)
diff --git a/akka-camel/src/main/scala/CamelContextLifecycle.scala b/akka-camel/src/main/scala/CamelContextLifecycle.scala
index 05c18396b8..32bb386dee 100644
--- a/akka-camel/src/main/scala/CamelContextLifecycle.scala
+++ b/akka-camel/src/main/scala/CamelContextLifecycle.scala
@@ -13,7 +13,7 @@ import se.scalablesolutions.akka.camel.component.TypedActorComponent
import se.scalablesolutions.akka.util.Logging
/**
- * Defines the lifecycle of a CamelContext. Allowed state transitions are
+ * Manages the lifecycle of a CamelContext. Allowed transitions are
* init -> start -> stop -> init -> ... etc.
*
* @author Martin Krasser
@@ -35,7 +35,7 @@ trait CamelContextLifecycle extends Logging {
/**
* Registry in which typed actors are TEMPORARILY registered during
- * creation of Camel routes to typed actors.
+ * creation of Camel routes to these actors.
*/
private[camel] var typedActorRegistry: Map[String, AnyRef] = _
@@ -63,7 +63,7 @@ trait CamelContextLifecycle extends Logging {
def started = _started
/**
- * Starts the CamelContext and ProducerTemplate.
+ * Starts the CamelContext and an associated ProducerTemplate.
*/
def start = {
context.start
@@ -73,7 +73,7 @@ trait CamelContextLifecycle extends Logging {
}
/**
- * Stops the CamelContext and ProducerTemplate.
+ * Stops the CamelContext and the associated ProducerTemplate.
*/
def stop = {
template.stop
@@ -90,11 +90,10 @@ trait CamelContextLifecycle extends Logging {
/**
* Initializes this lifecycle object with the given CamelContext. For the passed
- * CamelContext stream-caching is enabled. If applications want to disable stream-
+ * CamelContext, stream-caching is enabled. If applications want to disable stream-
* caching they can do so after this method returned and prior to calling start.
- * This method also registers a new
- * {@link se.scalablesolutions.akka.camel.component.TypedActorComponent} at
- * context under a name defined by TypedActorComponent.InternalSchema.
+ * This method also registers a new TypedActorComponent at the passes CamelContext
+ * under a name defined by TypedActorComponent.InternalSchema.
*/
def init(context: CamelContext) {
this.typedActorComponent = new TypedActorComponent
@@ -109,8 +108,7 @@ trait CamelContextLifecycle extends Logging {
}
/**
- * Makes a global CamelContext and ProducerTemplate accessible to applications. The lifecycle
- * of these objects is managed by se.scalablesolutions.akka.camel.CamelService.
+ * Manages a global CamelContext and an associated ProducerTemplate.
*/
object CamelContextManager extends CamelContextLifecycle {
override def context: CamelContext = super.context
diff --git a/akka-camel/src/main/scala/CamelService.scala b/akka-camel/src/main/scala/CamelService.scala
index 5fd8c9a66c..033fc2d01b 100644
--- a/akka-camel/src/main/scala/CamelService.scala
+++ b/akka-camel/src/main/scala/CamelService.scala
@@ -12,9 +12,10 @@ import se.scalablesolutions.akka.actor.{AspectInitRegistry, ActorRegistry}
import se.scalablesolutions.akka.util.{Bootable, Logging}
/**
- * Used by applications (and the Kernel) to publish consumer actors and typed actors via
- * Camel endpoints and to manage the life cycle of a a global CamelContext which can be
- * accessed via se.scalablesolutions.akka.camel.CamelContextManager.context.
+ * Publishes (untyped) consumer actors and typed consumer actors via Camel endpoints. Actors
+ * are published (asynchronously) when they are started and unpublished (asynchronously) when
+ * they are stopped. The CamelService is notified about actor start- and stop-events by
+ * registering listeners at ActorRegistry and AspectInitRegistry.
*
* @author Martin Krasser
*/
@@ -29,11 +30,11 @@ trait CamelService extends Bootable with Logging {
AspectInitRegistry.addListener(publishRequestor)
/**
- * Starts the CamelService. Any started actor that is a consumer actor will be (asynchronously)
+ * Starts this CamelService. Any started actor that is a consumer actor will be (asynchronously)
* published as Camel endpoint. Consumer actors that are started after this method returned will
* be published as well. Actor publishing is done asynchronously. A started (loaded) CamelService
* also publishes @consume annotated methods of typed actors that have been created
- * with TypedActor.newInstance(..) (and TypedActor.newInstance(..)
+ * with TypedActor.newInstance(..) (and TypedActor.newRemoteInstance(..)
* on a remote node).
*/
abstract override def onLoad = {
@@ -54,7 +55,8 @@ trait CamelService extends Bootable with Logging {
}
/**
- * Stops the CamelService.
+ * Stops this CamelService. All published consumer actors and typed consumer actor methods will be
+ * unpublished asynchronously.
*/
abstract override def onUnload = {
// Unregister this instance as current CamelService
@@ -98,24 +100,24 @@ trait CamelService extends Bootable with Logging {
def stop = onUnload
/**
- * Sets an expectation of the number of upcoming endpoint activations and returns
- * a {@link CountDownLatch} that can be used to wait for the activations to occur.
- * Endpoint activations that occurred in the past are not considered.
+ * Sets an expectation on the number of upcoming endpoint activations and returns
+ * a CountDownLatch that can be used to wait for the activations to occur. Endpoint
+ * activations that occurred in the past are not considered.
*/
def expectEndpointActivationCount(count: Int): CountDownLatch =
(consumerPublisher !! SetExpectedRegistrationCount(count)).as[CountDownLatch].get
/**
- * Sets an expectation of the number of upcoming endpoint de-activations and returns
- * a {@link CountDownLatch} that can be used to wait for the de-activations to occur.
- * Endpoint de-activations that occurred in the past are not considered.
+ * Sets an expectation on the number of upcoming endpoint de-activations and returns
+ * a CountDownLatch that can be used to wait for the de-activations to occur. Endpoint
+ * de-activations that occurred in the past are not considered.
*/
def expectEndpointDeactivationCount(count: Int): CountDownLatch =
(consumerPublisher !! SetExpectedUnregistrationCount(count)).as[CountDownLatch].get
}
/**
- * ...
+ * Manages a global CamelService (the 'current' CamelService).
*
* @author Martin Krasser
*/
@@ -128,11 +130,17 @@ object CamelServiceManager {
/**
* Starts a new CamelService and makes it the current CamelService.
+ *
+ * @see CamelService#start
+ * @see CamelService#onLoad
*/
def startCamelService = CamelServiceFactory.createCamelService.start
/**
* Stops the current CamelService.
+ *
+ * @see CamelService#stop
+ * @see CamelService#onUnload
*/
def stopCamelService = service.stop
@@ -159,12 +167,12 @@ object CamelServiceManager {
*/
object CamelServiceFactory {
/**
- * Creates a new CamelService instance
+ * Creates a new CamelService instance.
*/
def createCamelService: CamelService = new CamelService { }
/**
- * Creates a new CamelService instance
+ * Creates a new CamelService instance and initializes it with the given CamelContext.
*/
def createCamelService(camelContext: CamelContext): CamelService = {
CamelContextManager.init(camelContext)
diff --git a/akka-camel/src/main/scala/Consumer.scala b/akka-camel/src/main/scala/Consumer.scala
index ea07757a9c..db04c46abf 100644
--- a/akka-camel/src/main/scala/Consumer.scala
+++ b/akka-camel/src/main/scala/Consumer.scala
@@ -20,30 +20,24 @@ trait Consumer { self: Actor =>
def endpointUri: String
/**
- * Determines whether two-way communications with this consumer actor should
- * be done in blocking or non-blocking mode (default is non-blocking). One-way
- * communications never block.
+ * Determines whether two-way communications between an endpoint and this consumer actor
+ * should be done in blocking or non-blocking mode (default is non-blocking). This method
+ * doesn't have any effect on one-way communications (they'll never block).
*/
def blocking = false
}
/**
- * Java-friendly {@link Consumer} inherited by
+ * Java-friendly Consumer.
*
- *
- * - {@link UntypedConsumerActor}
- * - {@link RemoteUntypedConsumerActor}
- * - {@link UntypedConsumerTransactor}
- *
- *
- * implementations.
+ * @see UntypedConsumerActor
+ * @see RemoteUntypedConsumerActor
+ * @see UntypedConsumerTransactor
*
* @author Martin Krasser
*/
trait UntypedConsumer extends Consumer { self: UntypedActor =>
-
final override def endpointUri = getEndpointUri
-
final override def blocking = isBlocking
/**
@@ -52,9 +46,9 @@ trait UntypedConsumer extends Consumer { self: UntypedActor =>
def getEndpointUri(): String
/**
- * Determines whether two-way communications with this consumer actor should
- * be done in blocking or non-blocking mode (default is non-blocking). One-way
- * communications never block.
+ * Determines whether two-way communications between an endpoint and this consumer actor
+ * should be done in blocking or non-blocking mode (default is non-blocking). This method
+ * doesn't have any effect on one-way communications (they'll never block).
*/
def isBlocking() = super.blocking
}
@@ -89,7 +83,7 @@ private[camel] object Consumer {
* reference with a target actor that implements the Consumer trait. The
* target Consumer object is passed as argument to f. This
* method returns None if actorRef is not a valid reference
- * to a consumer actor, Some result otherwise.
+ * to a consumer actor, Some consumer actor otherwise.
*/
def forConsumer[T](actorRef: ActorRef)(f: Consumer => T): Option[T] = {
if (!actorRef.actor.isInstanceOf[Consumer]) None
diff --git a/akka-camel/src/main/scala/ConsumerPublisher.scala b/akka-camel/src/main/scala/ConsumerPublisher.scala
index 472d7d6dad..dfc1510ea6 100644
--- a/akka-camel/src/main/scala/ConsumerPublisher.scala
+++ b/akka-camel/src/main/scala/ConsumerPublisher.scala
@@ -28,7 +28,7 @@ private[camel] object ConsumerPublisher extends Logging {
}
/**
- * Stops route to the already un-registered consumer actor.
+ * Stops the route to the already un-registered consumer actor.
*/
def handleConsumerUnregistered(event: ConsumerUnregistered) {
CamelContextManager.context.stopRoute(event.uuid.toString)
@@ -48,7 +48,7 @@ private[camel] object ConsumerPublisher extends Logging {
}
/**
- * Stops route to the already un-registered consumer actor method.
+ * Stops the route to the already un-registered consumer actor method.
*/
def handleConsumerMethodUnregistered(event: ConsumerMethodUnregistered) {
val targetMethod = event.method.getName
@@ -62,10 +62,10 @@ private[camel] object ConsumerPublisher extends Logging {
/**
* Actor that publishes consumer actors and typed actor methods at Camel endpoints.
- * The Camel context used for publishing is CamelContextManager.context. This actor
- * accepts messages of type
+ * The Camel context used for publishing is obtained via CamelContextManager.context.
+ * This actor accepts messages of type
* se.scalablesolutions.akka.camel.ConsumerRegistered,
- * se.scalablesolutions.akka.camel.ConsumerUnregistered.
+ * se.scalablesolutions.akka.camel.ConsumerUnregistered,
* se.scalablesolutions.akka.camel.ConsumerMethodRegistered and
* se.scalablesolutions.akka.camel.ConsumerMethodUnregistered.
*
@@ -110,7 +110,7 @@ private[camel] case class SetExpectedRegistrationCount(num: Int)
private[camel] case class SetExpectedUnregistrationCount(num: Int)
/**
- * Defines an abstract route to a target which is either an actor or an typed actor method..
+ * Abstract route to a target which is either an actor or an typed actor method.
*
* @param endpointUri endpoint URI of the consumer actor or typed actor method.
* @param id actor identifier or typed actor identifier (registry key).
@@ -135,9 +135,9 @@ private[camel] abstract class ConsumerRoute(endpointUri: String, id: String) ext
}
/**
- * Defines the route to a consumer actor.
+ * Defines the route to a (untyped) consumer actor.
*
- * @param endpointUri endpoint URI of the consumer actor
+ * @param endpointUri endpoint URI of the (untyped) consumer actor
* @param uuid actor uuid
* @param blocking true for blocking in-out exchanges, false otherwise
*
@@ -148,7 +148,7 @@ private[camel] class ConsumerActorRoute(endpointUri: String, uuid: Uuid, blockin
}
/**
- * Defines the route to an typed actor method..
+ * Defines the route to a typed actor method.
*
* @param endpointUri endpoint URI of the consumer actor method
* @param id typed actor identifier
@@ -162,10 +162,10 @@ private[camel] class ConsumerMethodRoute(val endpointUri: String, id: String, me
/**
* A registration listener that triggers publication of consumer actors and typed actor
- * methods as well as un-publication of consumer actors. This actor needs to be initialized
- * with a PublishRequestorInit command message for obtaining a reference to
- * a publisher actor. Before initialization it buffers all outbound messages
- * and delivers them to the publisher when receiving a
+ * methods as well as un-publication of consumer actors and typed actor methods. This actor
+ * needs to be initialized with a PublishRequestorInit command message for
+ * obtaining a reference to a publisher actor. Before initialization it buffers
+ * all outbound messages and delivers them to the publisher when receiving a
* PublishRequestorInit message. After initialization, outbound messages are
* delivered directly without buffering.
*
@@ -273,7 +273,7 @@ private[camel] case class ConsumerMethodUnregistered(typedActor: AnyRef, init: A
*/
private[camel] object ConsumerRegistered {
/**
- * Optionally creates an ConsumerRegistered event message for a consumer actor or None if
+ * Creates an ConsumerRegistered event message for a consumer actor or None if
* actorRef is not a consumer actor.
*/
def forConsumer(actorRef: ActorRef): Option[ConsumerRegistered] = {
@@ -288,7 +288,7 @@ private[camel] object ConsumerRegistered {
*/
private[camel] object ConsumerUnregistered {
/**
- * Optionally creates an ConsumerUnregistered event message for a consumer actor or None if
+ * Creates an ConsumerUnregistered event message for a consumer actor or None if
* actorRef is not a consumer actor.
*/
def forConsumer(actorRef: ActorRef): Option[ConsumerUnregistered] = {
@@ -327,8 +327,8 @@ private[camel] object ConsumerMethod {
*/
private[camel] object ConsumerMethodRegistered {
/**
- * Creates a list of ConsumerMethodRegistered event messages for an typed actor or an empty
- * list if the typed actor is a proxy for an remote typed actor or the typed actor doesn't
+ * Creates a list of ConsumerMethodRegistered event messages for a typed actor or an empty
+ * list if the typed actor is a proxy for a remote typed actor or the typed actor doesn't
* have any @consume annotated methods.
*/
def forConsumer(typedActor: AnyRef, init: AspectInit): List[ConsumerMethodRegistered] = {
@@ -343,8 +343,8 @@ private[camel] object ConsumerMethodRegistered {
*/
private[camel] object ConsumerMethodUnregistered {
/**
- * Creates a list of ConsumerMethodUnregistered event messages for an typed actor or an empty
- * list if the typed actor is a proxy for an remote typed actor or the typed actor doesn't
+ * Creates a list of ConsumerMethodUnregistered event messages for a typed actor or an empty
+ * list if the typed actor is a proxy for a remote typed actor or the typed actor doesn't
* have any @consume annotated methods.
*/
def forConsumer(typedActor: AnyRef, init: AspectInit): List[ConsumerMethodUnregistered] = {
diff --git a/akka-camel/src/main/scala/Message.scala b/akka-camel/src/main/scala/Message.scala
index a834568a22..d5cfd23faf 100644
--- a/akka-camel/src/main/scala/Message.scala
+++ b/akka-camel/src/main/scala/Message.scala
@@ -10,7 +10,7 @@ import org.apache.camel.util.ExchangeHelper
/**
* An immutable representation of a Camel message. Actor classes that mix in
* se.scalablesolutions.akka.camel.Producer or
- * se.scalablesolutions.akka.camel.Consumer use this message type for communication.
+ * se.scalablesolutions.akka.camel.Consumer usually use this message type for communication.
*
* @author Martin Krasser
*/
@@ -264,8 +264,8 @@ class CamelMessageAdapter(val cm: CamelMessage) {
/**
* Defines conversion methods to CamelExchangeAdapter and CamelMessageAdapter.
- * Imported by applications
- * that implicitly want to use conversion methods of CamelExchangeAdapter and CamelMessageAdapter.
+ * Imported by applications that implicitly want to use conversion methods of
+ * CamelExchangeAdapter and CamelMessageAdapter.
*/
object CamelMessageConversion {
diff --git a/akka-camel/src/main/scala/Producer.scala b/akka-camel/src/main/scala/Producer.scala
index 0be07e9737..3313c1d0be 100644
--- a/akka-camel/src/main/scala/Producer.scala
+++ b/akka-camel/src/main/scala/Producer.scala
@@ -24,7 +24,7 @@ trait ProducerSupport { this: Actor =>
private val headersToCopyDefault = Set(Message.MessageExchangeId)
/**
- * Endpoint object resolved from current CamelContext with
+ * Endpoint object resolved from the current CamelContext with
* endpointUri.
*/
private lazy val endpoint = CamelContextManager.context.getEndpoint(endpointUri)
@@ -36,8 +36,8 @@ trait ProducerSupport { this: Actor =>
/**
* If set to false (default), this producer expects a response message from the Camel endpoint.
- * If set to true, this producer communicates with the Camel endpoint with an in-only message
- * exchange pattern (fire and forget).
+ * If set to true, this producer initiates an in-only message exchange with the Camel endpoint
+ * (fire and forget).
*/
def oneway: Boolean = false
@@ -62,13 +62,17 @@ trait ProducerSupport { this: Actor =>
}
/**
- * Produces msg as exchange of given pattern to the endpoint specified by
- * endpointUri. After producing to the endpoint the processing result is passed as argument
- * to receiveAfterProduce. If the result was returned synchronously by the endpoint then
- * receiveAfterProduce is called synchronously as well. If the result was returned asynchronously,
- * the receiveAfterProduce is called asynchronously as well. This is done by wrapping the result,
- * adding it to this producers mailbox, unwrapping it once it is received and calling
- * receiveAfterProduce. The original sender and senderFuture are thereby preserved.
+ * Initiates a message exchange of given pattern with the endpoint specified by
+ * endpointUri. The in-message of the initiated exchange is the canonical form
+ * of msg. After sending the in-message, the processing result (response) is passed
+ * as argument to receiveAfterProduce. If the response is received synchronously from
+ * the endpoint then receiveAfterProduce is called synchronously as well. If the
+ * response is received asynchronously, the receiveAfterProduce is called
+ * asynchronously. This is done by wrapping the response, adding it to this producers
+ * mailbox, unwrapping it and calling receiveAfterProduce. The original
+ * sender and senderFuture are thereby preserved.
+ *
+ * @see Message#canonicalize(Any)
*
* @param msg message to produce
* @param pattern exchange pattern
@@ -106,8 +110,8 @@ trait ProducerSupport { this: Actor =>
/**
* Produces msg to the endpoint specified by endpointUri. Before the message is
- * actually produced it is pre-processed by calling receiveBeforeProduce. If oneway
- * is true an in-only message exchange is initiated, otherwise an in-out message exchange.
+ * actually sent it is pre-processed by calling receiveBeforeProduce. If oneway
+ * is true, an in-only message exchange is initiated, otherwise an in-out message exchange.
*
* @see Producer#produce(Any, ExchangePattern)
*/
@@ -132,17 +136,18 @@ trait ProducerSupport { this: Actor =>
}
/**
- * Called after the a result was received from the endpoint specified by endpointUri. The
- * result is passed as argument. By default, this method replies the result back to the original sender
- * if oneway is false. If oneway is true then nothing is done. This method may
- * be overridden by subtraits or subclasses.
+ * Called after a response was received from the endpoint specified by endpointUri. The
+ * response is passed as argument. By default, this method sends the response back to the original sender
+ * if oneway is false. If oneway is true, nothing is
+ * done. This method may be overridden by subtraits or subclasses (e.g. to forward responses to another
+ * actor).
*/
protected def receiveAfterProduce: Receive = {
case msg => if (!oneway) self.reply(msg)
}
/**
- * Creates a new Exchange with given pattern from the endpoint specified by
+ * Creates a new Exchange of given pattern from the endpoint specified by
* endpointUri.
*/
private def createExchange(pattern: ExchangePattern): Exchange = endpoint.createExchange(pattern)
@@ -158,25 +163,26 @@ trait ProducerSupport { this: Actor =>
}
/**
- * Mixed in by Actor implementations that produce messages to Camel endpoints.
+ * Mixed in by Actor implementations to produce messages to Camel endpoints.
*/
trait Producer extends ProducerSupport { this: Actor =>
/**
- * Default implementation of Actor.receive
+ * Default implementation of Actor.receive. Any messages received by this actors
+ * will be produced to the endpoint specified by endpointUri.
*/
protected def receive = produce
}
/**
- * Java-friendly {@link ProducerSupport} inherited by {@link UntypedProducerActor} implementations.
+ * Java-friendly ProducerSupport.
+ *
+ * @see UntypedProducerActor
*
* @author Martin Krasser
*/
trait UntypedProducer extends ProducerSupport { this: UntypedActor =>
-
final override def endpointUri = getEndpointUri
-
final override def oneway = isOneway
final override def receiveBeforeProduce = {
@@ -213,10 +219,10 @@ trait UntypedProducer extends ProducerSupport { this: UntypedActor =>
def onReceiveBeforeProduce(message: Any): Any = super.receiveBeforeProduce(message)
/**
- * Called after the a result was received from the endpoint specified by getEndpointUri. The
- * result is passed as argument. By default, this method replies the result back to the original sender
- * if isOneway returns false. If isOneway returns true then nothing is done. This
- * method may be overridden by subclasses.
+ * Called after a response was received from the endpoint specified by endpointUri. The
+ * response is passed as argument. By default, this method sends the response back to the original sender
+ * if oneway is false. If oneway is true, nothing is
+ * done. This method may be overridden by subclasses (e.g. to forward responses to another actor).
*/
@throws(classOf[Exception])
def onReceiveAfterProduce(message: Any): Unit = super.receiveAfterProduce(message)
diff --git a/akka-camel/src/main/scala/component/ActorComponent.scala b/akka-camel/src/main/scala/component/ActorComponent.scala
index 57afd8d500..297a4c3a84 100644
--- a/akka-camel/src/main/scala/component/ActorComponent.scala
+++ b/akka-camel/src/main/scala/component/ActorComponent.scala
@@ -45,12 +45,13 @@ class ActorComponent extends DefaultComponent {
}
/**
- * Camel endpoint for referencing an (untyped) actor. The actor reference is given by the endpoint URI.
- * An actor can be referenced by its ActorRef.id or its ActorRef.uuid.
- * Supported endpoint URI formats are
- * actor:<actorid>,
- * actor:id:<actorid> and
- * actor:uuid:<actoruuid>.
+ * Camel endpoint for sending messages to and receiving replies from (untyped) actors. Actors
+ * are referenced using actor endpoint URIs of the following format:
+ * actor:,
+ * actor:id: and
+ * actor:uuid:,
+ * where actor-id refers to ActorRef.id and actor-uuid
+ * refers to the String-representation od ActorRef.uuid.
*
* @see se.scalablesolutions.akka.camel.component.ActorComponent
* @see se.scalablesolutions.akka.camel.component.ActorProducer
@@ -63,8 +64,9 @@ class ActorEndpoint(uri: String,
val uuid: Option[Uuid]) extends DefaultEndpoint(uri, comp) {
/**
- * Blocking of caller thread during two-way message exchanges with consumer actors. This is set
- * via the blocking=true|false endpoint URI parameter. If omitted blocking is false.
+ * Whether to block caller thread during two-way message exchanges with (untyped) actors. This is
+ * set via the blocking=true|false endpoint URI parameter. Default value is
+ * false.
*/
@BeanProperty var blocking: Boolean = false
@@ -86,9 +88,18 @@ class ActorEndpoint(uri: String,
}
/**
- * Sends the in-message of an exchange to an (untyped) actor. If the exchange pattern is out-capable and
- * blocking is enabled then the producer waits for a reply (using the !! operator),
- * otherwise the ! operator is used for sending the message.
+ * Sends the in-message of an exchange to an (untyped) actor.
+ *
+ * - If the exchange pattern is out-capable and
blocking is set to
+ * true then the producer waits for a reply, using the !! operator.
+ * - If the exchange pattern is out-capable and
blocking is set to
+ * false then the producer sends the message using the ! operator, together
+ * with a callback handler. The callback handler is an ActorRef that can be
+ * used by the receiving actor to asynchronously reply to the route that is sending the
+ * message.
+ * - If the exchange pattern is in-only then the producer sends the message using the
+ * ! operator.
+ *
*
* @see se.scalablesolutions.akka.camel.component.ActorComponent
* @see se.scalablesolutions.akka.camel.component.ActorEndpoint
@@ -183,11 +194,11 @@ private[akka] object AsyncCallbackAdapter {
}
/**
- * Adapts an AsyncCallback to ActorRef.!. Used by other actors to reply
- * asynchronously to Camel with ActorRef.reply.
+ * Adapts an ActorRef to a Camel AsyncCallback. Used by receiving actors to reply
+ * asynchronously to Camel routes with ActorRef.reply.
*
* Please note that this adapter can only be used locally at the moment which should not
- * be a problem is most situations as Camel endpoints are only activated for local actor references,
+ * be a problem is most situations since Camel endpoints are only activated for local actor references,
* never for remote references.
*
* @author Martin Krasser
@@ -204,8 +215,9 @@ private[akka] class AsyncCallbackAdapter(exchange: Exchange, callback: AsyncCall
}
/**
- * Writes the reply message to exchange and uses callback to
- * generate completion notifications.
+ * Populates the initial exchange with the reply message and uses the
+ * callback handler to notify Camel about the asynchronous completion of the message
+ * exchange.
*
* @param message reply message
* @param sender ignored
diff --git a/akka-camel/src/main/scala/component/TypedActorComponent.scala b/akka-camel/src/main/scala/component/TypedActorComponent.scala
index 2a48cf9fc4..542705d0c6 100644
--- a/akka-camel/src/main/scala/component/TypedActorComponent.scala
+++ b/akka-camel/src/main/scala/component/TypedActorComponent.scala
@@ -21,7 +21,7 @@ object TypedActorComponent {
/**
* Camel component for exchanging messages with typed actors. This component
- * tries to obtain the typed actor from the typedActorRegistry
+ * tries to obtain the typed actor from its typedActorRegistry
* first. If it's not there it tries to obtain it from the CamelContext's registry.
*
* @see org.apache.camel.component.bean.BeanComponent
@@ -32,9 +32,9 @@ class TypedActorComponent extends BeanComponent {
val typedActorRegistry = new ConcurrentHashMap[String, AnyRef]
/**
- * Creates a {@link org.apache.camel.component.bean.BeanEndpoint} with a custom
- * bean holder that uses typedActorRegistry for getting access to
- * typed actors (beans).
+ * Creates an org.apache.camel.component.bean.BeanEndpoint with a custom
+ * bean holder that uses typedActorRegistry for getting access to typed
+ * actors (beans).
*
* @see se.scalablesolutions.akka.camel.component.TypedActorHolder
*/
@@ -51,7 +51,7 @@ class TypedActorComponent extends BeanComponent {
}
/**
- * {@link org.apache.camel.component.bean.BeanHolder} implementation that uses a custom
+ * org.apache.camel.component.bean.BeanHolder implementation that uses a custom
* registry for getting access to typed actors.
*
* @author Martin Krasser
@@ -60,13 +60,16 @@ class TypedActorHolder(typedActorRegistry: Map[String, AnyRef], context: CamelCo
extends RegistryBean(context, name) {
/**
- * Returns an {@link se.scalablesolutions.akka.camel.component.TypedActorInfo} instance.
+ * Returns an se.scalablesolutions.akka.camel.component.TypedActorInfo instance.
*/
override def getBeanInfo: BeanInfo =
new TypedActorInfo(getContext, getBean.getClass, getParameterMappingStrategy)
/**
- * Obtains an typed actor from typedActorRegistry.
+ * Obtains a typed actor from typedActorRegistry. If the typed actor cannot
+ * be found then this method tries to obtain the actor from the CamelContext's registry.
+ *
+ * @return a typed actor or null.
*/
override def getBean: AnyRef = {
val bean = typedActorRegistry.get(getName)
@@ -75,7 +78,7 @@ class TypedActorHolder(typedActorRegistry: Map[String, AnyRef], context: CamelCo
}
/**
- * Provides typed actor meta information.
+ * Typed actor meta information.
*
* @author Martin Krasser
*/
From 4ea4158cde3b421427cbd1031e11694115501282 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jonas=20Bon=C3=A9r?=
Date: Fri, 24 Sep 2010 20:28:23 +0200
Subject: [PATCH 15/82] Changed file-based mailbox creation
---
akka-actor/src/main/scala/dispatch/MailboxHandling.scala | 5 +++--
akka-actor/src/main/scala/util/ReflectiveAccess.scala | 7 ++++---
2 files changed, 7 insertions(+), 5 deletions(-)
diff --git a/akka-actor/src/main/scala/dispatch/MailboxHandling.scala b/akka-actor/src/main/scala/dispatch/MailboxHandling.scala
index d12c326bbf..fe84e04ff2 100644
--- a/akka-actor/src/main/scala/dispatch/MailboxHandling.scala
+++ b/akka-actor/src/main/scala/dispatch/MailboxHandling.scala
@@ -4,7 +4,7 @@
package se.scalablesolutions.akka.dispatch
-import se.scalablesolutions.akka.actor.{Actor, ActorRef, ActorInitializationException}
+import se.scalablesolutions.akka.actor.{Actor, ActorType, ActorRef, ActorInitializationException}
import se.scalablesolutions.akka.util.{SimpleLock, Duration, HashCode, Logging}
import se.scalablesolutions.akka.util.ReflectiveAccess.EnterpriseModule
import se.scalablesolutions.akka.AkkaException
@@ -104,7 +104,8 @@ trait MailboxFactory {
* Creates and returns a durable mailbox for the given actor.
*/
protected def createDurableMailbox(actorRef: ActorRef, mailboxType: DurableMailboxType): AnyRef = mailboxType match {
- case FileBasedDurableMailbox(serializer) => EnterpriseModule.createFileBasedMailbox(actorRef.uuid, serializer).asInstanceOf[MessageQueue]
+ // FIXME make generic (work for TypedActor as well)
+ case FileBasedDurableMailbox(serializer) => EnterpriseModule.createFileBasedMailbox(actorRef.uuid, ActorType.ScalaActor, None).asInstanceOf[MessageQueue]
case RedisBasedDurableMailbox(serializer) => throw new UnsupportedOperationException("RedisBasedDurableMailbox is not yet supported")
case BeanstalkBasedDurableMailbox(serializer) => throw new UnsupportedOperationException("BeanstalkBasedDurableMailbox is not yet supported")
case ZooKeeperBasedDurableMailbox(serializer) => throw new UnsupportedOperationException("ZooKeeperBasedDurableMailbox is not yet supported")
diff --git a/akka-actor/src/main/scala/util/ReflectiveAccess.scala b/akka-actor/src/main/scala/util/ReflectiveAccess.scala
index 9eec8f076b..974250bc84 100644
--- a/akka-actor/src/main/scala/util/ReflectiveAccess.scala
+++ b/akka-actor/src/main/scala/util/ReflectiveAccess.scala
@@ -222,12 +222,13 @@ object ReflectiveAccess extends Logging {
def ensureEnterpriseEnabled = if (!isEnterpriseEnabled) throw new ModuleNotAvailableException(
"Feature is only available in Akka Enterprise")
- def createFileBasedMailbox(name: String, serializer: Serializer): FileBasedMailbox = {
+ def createFileBasedMailbox(
+ name: String, actorType: ActorType, typedActorInfo: Option[Tuple2[String, String]]): FileBasedMailbox = {
ensureEnterpriseEnabled
createInstance(
"se.scalablesolutions.akka.cluster.FileBasedMailbox",
- Array(classOf[String], serializerClass.get),
- Array(name, serializer).asInstanceOf[Array[AnyRef]],
+ Array(classOf[String], classOf[ActorType], classOf[Option[Tuple2[String, String]]]),
+ Array(name, actorType, typedActorInfo).asInstanceOf[Array[AnyRef]],
loader)
.getOrElse(throw new IllegalActorStateException("Could not create file-based mailbox"))
.asInstanceOf[FileBasedMailbox]
From 96c9fecf0de488e2e2308e997163b4e2da7c02a7 Mon Sep 17 00:00:00 2001
From: ticktock
Date: Fri, 24 Sep 2010 19:38:28 -0400
Subject: [PATCH 16/82] Refactor to utilize only one voldemort store per
datastructure type
---
.../main/scala/VoldemortStorageBackend.scala | 54 ++++++++++---------
.../src/test/resources/config/stores.xml | 19 +------
.../scala/VoldemortStorageBackendSuite.scala | 10 ++--
config/akka-reference.conf | 7 ++-
4 files changed, 37 insertions(+), 53 deletions(-)
diff --git a/akka-persistence/akka-persistence-voldemort/src/main/scala/VoldemortStorageBackend.scala b/akka-persistence/akka-persistence-voldemort/src/main/scala/VoldemortStorageBackend.scala
index b5c1023970..e08c45d159 100644
--- a/akka-persistence/akka-persistence-voldemort/src/main/scala/VoldemortStorageBackend.scala
+++ b/akka-persistence/akka-persistence-voldemort/src/main/scala/VoldemortStorageBackend.scala
@@ -33,23 +33,22 @@ MapStorageBackend[Array[Byte], Array[Byte]] with
case None => getClientConfig(new HashMap[String, String] + (bootstrapUrlsProp -> "tcp://localhost:6666"))
}
val refStore = config.getString("akka.storage.voldemort.store.ref", "Refs")
- val mapKeyStore = config.getString("akka.storage.voldemort.store.map-key", "MapKeys")
- val mapValueStore = config.getString("akka.storage.voldemort.store.map-value", "MapValues")
+ val mapStore = config.getString("akka.storage.voldemort.store.map", "Maps")
val vectorStore = config.getString("akka.storage.voldemort.store.vector", "Vectors")
val queueStore = config.getString("akka.storage.voldemort.store.queue", "Queues")
var storeClientFactory: StoreClientFactory = null
var refClient: StoreClient[String, Array[Byte]] = null
- var mapKeyClient: StoreClient[String, Array[Byte]] = null
- var mapValueClient: StoreClient[Array[Byte], Array[Byte]] = null
+ var mapClient: StoreClient[Array[Byte], Array[Byte]] = null
var vectorClient: StoreClient[Array[Byte], Array[Byte]] = null
var queueClient: StoreClient[Array[Byte], Array[Byte]] = null
initStoreClients
val underscoreBytesUTF8 = "_".getBytes("UTF-8")
- val vectorSizeIndex = -1
- val queueHeadIndex = -1
- val queueTailIndex = -2
+ val mapKeysIndex = getIndexedBytes(-1)
+ val vectorSizeIndex = getIndexedBytes(-1)
+ val queueHeadIndex = getIndexedBytes(-1)
+ val queueTailIndex = getIndexedBytes(-2)
case class QueueMetadata(head: Int, tail: Int) {
def size = tail - head
//worry about wrapping etc
@@ -85,7 +84,7 @@ MapStorageBackend[Array[Byte], Array[Byte]] with
private def getKeyValues(name: String, keys: SortedSet[Array[Byte]]): List[(Array[Byte], Array[Byte])] = {
val all: JMap[Array[Byte], Versioned[Array[Byte]]] =
- mapValueClient.getAll(JavaConversions.asIterable(keys.map {
+ mapClient.getAll(JavaConversions.asIterable(keys.map {
mapKey => getKey(name, mapKey)
}))
@@ -108,7 +107,7 @@ MapStorageBackend[Array[Byte], Array[Byte]] with
}
def getMapStorageEntryFor(name: String, key: Array[Byte]): Option[Array[Byte]] = {
- val result: Array[Byte] = mapValueClient.getValue(getKey(name, key))
+ val result: Array[Byte] = mapClient.getValue(getKey(name, key))
result match {
case null => None
case _ => Some(result)
@@ -119,7 +118,7 @@ MapStorageBackend[Array[Byte], Array[Byte]] with
var keys = getMapKeys(name)
keys -= key
putMapKeys(name, keys)
- mapValueClient.delete(getKey(name, key))
+ mapClient.delete(getKey(name, key))
}
@@ -127,13 +126,13 @@ MapStorageBackend[Array[Byte], Array[Byte]] with
val keys = getMapKeys(name)
keys.foreach {
key =>
- mapValueClient.delete(getKey(name, key))
+ mapClient.delete(getKey(name, key))
}
- mapKeyClient.delete(name)
+ mapClient.delete(getKey(name, mapKeysIndex))
}
def insertMapStorageEntryFor(name: String, key: Array[Byte], value: Array[Byte]) = {
- mapValueClient.put(getKey(name, key), value)
+ mapClient.put(getKey(name, key), value)
var keys = getMapKeys(name)
keys += key
putMapKeys(name, keys)
@@ -142,7 +141,7 @@ MapStorageBackend[Array[Byte], Array[Byte]] with
def insertMapStorageEntriesFor(name: String, entries: List[(Array[Byte], Array[Byte])]) = {
val newKeys = entries.map {
case (key, value) => {
- mapValueClient.put(getKey(name, key), value)
+ mapClient.put(getKey(name, key), value)
key
}
}
@@ -152,16 +151,16 @@ MapStorageBackend[Array[Byte], Array[Byte]] with
}
def putMapKeys(name: String, keys: SortedSet[Array[Byte]]) = {
- mapKeyClient.put(name, SortedSetSerializer.toBytes(keys))
+ mapClient.put(getKey(name, mapKeysIndex), SortedSetSerializer.toBytes(keys))
}
def getMapKeys(name: String): SortedSet[Array[Byte]] = {
- SortedSetSerializer.fromBytes(mapKeyClient.getValue(name, Array.empty[Byte]))
+ SortedSetSerializer.fromBytes(mapClient.getValue(getKey(name, mapKeysIndex), Array.empty[Byte]))
}
def getVectorStorageSizeFor(name: String): Int = {
- IntSerializer.fromBytes(vectorClient.getValue(getIndexedKey(name, vectorSizeIndex), IntSerializer.toBytes(0)))
+ IntSerializer.fromBytes(vectorClient.getValue(getKey(name, vectorSizeIndex), IntSerializer.toBytes(0)))
}
@@ -205,7 +204,7 @@ MapStorageBackend[Array[Byte], Array[Byte]] with
val size = getVectorStorageSizeFor(name)
vectorClient.put(getIndexedKey(name, index), elem)
if (size < index + 1) {
- vectorClient.put(getIndexedKey(name, vectorSizeIndex), IntSerializer.toBytes(index + 1))
+ vectorClient.put(getKey(name, vectorSizeIndex), IntSerializer.toBytes(index + 1))
}
}
@@ -216,7 +215,7 @@ MapStorageBackend[Array[Byte], Array[Byte]] with
vectorClient.put(getIndexedKey(name, size), element)
size += 1
}
- vectorClient.put(getIndexedKey(name, vectorSizeIndex), IntSerializer.toBytes(size))
+ vectorClient.put(getKey(name, vectorSizeIndex), IntSerializer.toBytes(size))
}
def insertVectorStorageEntryFor(name: String, element: Array[Byte]) = {
@@ -244,13 +243,13 @@ MapStorageBackend[Array[Byte], Array[Byte]] with
val mdata = getQueueMetadata(name)
val key = getIndexedKey(name, mdata.tail)
queueClient.put(key, item)
- queueClient.put(getIndexedKey(name, queueTailIndex), IntSerializer.toBytes(mdata.tail + 1))
- Some (mdata.size + 1)
+ queueClient.put(getKey(name, queueTailIndex), IntSerializer.toBytes(mdata.tail + 1))
+ Some(mdata.size + 1)
}
def getQueueMetadata(name: String): QueueMetadata = {
- val keys = List(getIndexedKey(name, queueHeadIndex), getIndexedKey(name, queueTailIndex))
+ val keys = List(getKey(name, queueHeadIndex), getKey(name, queueTailIndex))
val qdata = JavaConversions.asMap(queueClient.getAll(JavaConversions.asIterable(keys)))
val values = keys.map {
qdata.get(_) match {
@@ -278,12 +277,16 @@ MapStorageBackend[Array[Byte], Array[Byte]] with
theKey
}
- def getIndexedKey(owner: String, index: Int): Array[Byte] = {
+ def getIndexedBytes(index: Int): Array[Byte] = {
val indexbytes = IntSerializer.toBytes(index)
val theIndexKey = new Array[Byte](underscoreBytesUTF8.length + indexbytes.length)
System.arraycopy(underscoreBytesUTF8, 0, theIndexKey, 0, underscoreBytesUTF8.length)
System.arraycopy(indexbytes, 0, theIndexKey, underscoreBytesUTF8.length, indexbytes.length)
- getKey(owner, theIndexKey)
+ theIndexKey
+ }
+
+ def getIndexedKey(owner: String, index: Int): Array[Byte] = {
+ getKey(owner, getIndexedBytes(index))
}
def getIndexFromVectorValueKey(owner: String, key: Array[Byte]): Int = {
@@ -318,8 +321,7 @@ MapStorageBackend[Array[Byte], Array[Byte]] with
}
}
refClient = storeClientFactory.getStoreClient(refStore)
- mapKeyClient = storeClientFactory.getStoreClient(mapKeyStore)
- mapValueClient = storeClientFactory.getStoreClient(mapValueStore)
+ mapClient = storeClientFactory.getStoreClient(mapStore)
vectorClient = storeClientFactory.getStoreClient(vectorStore)
queueClient = storeClientFactory.getStoreClient(queueStore)
}
diff --git a/akka-persistence/akka-persistence-voldemort/src/test/resources/config/stores.xml b/akka-persistence/akka-persistence-voldemort/src/test/resources/config/stores.xml
index de666a219f..203ac20479 100644
--- a/akka-persistence/akka-persistence-voldemort/src/test/resources/config/stores.xml
+++ b/akka-persistence/akka-persistence-voldemort/src/test/resources/config/stores.xml
@@ -17,7 +17,7 @@
- MapValues
+ Maps
1
1
1
@@ -32,23 +32,6 @@
identity
-
- MapKeys
- 1
- 1
- 1
- 1
- 1
- memory
- client
-
- string
- utf8
-
-
- identity
-
-
Vectors
1
diff --git a/akka-persistence/akka-persistence-voldemort/src/test/scala/VoldemortStorageBackendSuite.scala b/akka-persistence/akka-persistence-voldemort/src/test/scala/VoldemortStorageBackendSuite.scala
index 5f27771bae..613181cbd2 100644
--- a/akka-persistence/akka-persistence-voldemort/src/test/scala/VoldemortStorageBackendSuite.scala
+++ b/akka-persistence/akka-persistence-voldemort/src/test/scala/VoldemortStorageBackendSuite.scala
@@ -34,8 +34,8 @@ class VoldemortStorageBackendSuite extends FunSuite with ShouldMatchers with Emb
test("that map key storage and retrieval works") {
val key = "testmapKey"
val mapKeys = new TreeSet[Array[Byte]] + bytes("key1")
- mapKeyClient.delete(key)
- mapKeyClient.getValue(key, SortedSetSerializer.toBytes(emptySet)) should equal(SortedSetSerializer.toBytes(emptySet))
+ mapClient.delete(getKey(key, mapKeysIndex))
+ mapClient.getValue(getKey(key, mapKeysIndex), SortedSetSerializer.toBytes(emptySet)) should equal(SortedSetSerializer.toBytes(emptySet))
putMapKeys(key, mapKeys)
getMapKeys(key) should equal(mapKeys)
}
@@ -43,8 +43,8 @@ class VoldemortStorageBackendSuite extends FunSuite with ShouldMatchers with Emb
test("that map value storage and retrieval works") {
val key = bytes("keyForTestingMapValueClient")
val value = bytes("value for testing map value client")
- mapValueClient.put(key, value)
- mapValueClient.getValue(key, empty) should equal(value)
+ mapClient.put(key, value)
+ mapClient.getValue(key, empty) should equal(value)
}
@@ -99,7 +99,7 @@ class VoldemortStorageBackendSuite extends FunSuite with ShouldMatchers with Emb
val key = "vectorApiKey"
val value = bytes("Some bytes we want to store in a vector")
val updatedValue = bytes("Some updated bytes we want to store in a vector")
- vectorClient.delete(getIndexedKey(key, vectorSizeIndex))
+ vectorClient.delete(getKey(key, vectorSizeIndex))
vectorClient.delete(getIndexedKey(key, 0))
vectorClient.delete(getIndexedKey(key, 1))
getVectorStorageEntryFor(key, 0) should be(empty)
diff --git a/config/akka-reference.conf b/config/akka-reference.conf
index a8bfcb332d..4b510a960e 100644
--- a/config/akka-reference.conf
+++ b/config/akka-reference.conf
@@ -173,13 +173,12 @@ akka {
voldemort {
store {
ref = "Refs" # Voldemort Store Used to Persist Refs. Use string serializer for keys, identity serializer for values
- map-keys = "MapKeys" # Voldemort Store Used to Persist Map Keys. Use string serializer for keys, identity serializer for values
- map-values = "MapValues" # Voldemort Store Used to Persist Map Values. Use identity serializer for keys, identity serializer for values
- vector = "Vectors" # Voldemort Store Used to Persist Vector Sizes. Use string serializer for keys, identity serializer for values
+ maps = "Maps" # Voldemort Store Used to Persist Map Keys. Use identity serializer for keys, identity serializer for values
+ vector = "Vectors" # Voldemort Store Used to Persist Vector Sizes. Use identity serializer for keys, identity serializer for values
queue = "Queues" # Voldemort Store Used to Persist Vector Values. Use identity serializer for keys, identity serializer for values
}
- client { # The KeyValue pairs under client are converted to java Properties and used to construct the ClientConfig
+ client { # The KeyValue pairs under client are converted to java Properties and used to construct the Voldemort ClientConfig
bootstrap_urls = "tcp://localhost:6666" # All Valid Voldemort Client properties are valid here, in string form
}
}
From b9146e61f9b0266f55d101de3cede5f1dc1e8225 Mon Sep 17 00:00:00 2001
From: ticktock
Date: Fri, 24 Sep 2010 23:52:27 -0400
Subject: [PATCH 17/82] more queue implementation
---
.../main/scala/VoldemortStorageBackend.scala | 80 ++++++++++++++++---
.../scala/VoldemortStorageBackendSuite.scala | 32 ++++++++
2 files changed, 102 insertions(+), 10 deletions(-)
diff --git a/akka-persistence/akka-persistence-voldemort/src/main/scala/VoldemortStorageBackend.scala b/akka-persistence/akka-persistence-voldemort/src/main/scala/VoldemortStorageBackend.scala
index e08c45d159..7cfc24c092 100644
--- a/akka-persistence/akka-persistence-voldemort/src/main/scala/VoldemortStorageBackend.scala
+++ b/akka-persistence/akka-persistence-voldemort/src/main/scala/VoldemortStorageBackend.scala
@@ -49,10 +49,7 @@ MapStorageBackend[Array[Byte], Array[Byte]] with
val vectorSizeIndex = getIndexedBytes(-1)
val queueHeadIndex = getIndexedBytes(-1)
val queueTailIndex = getIndexedBytes(-2)
- case class QueueMetadata(head: Int, tail: Int) {
- def size = tail - head
- //worry about wrapping etc
- }
+
implicit val byteOrder = new Ordering[Array[Byte]] {
override def compare(x: Array[Byte], y: Array[Byte]) = ByteUtils.compare(x, y)
@@ -224,7 +221,13 @@ MapStorageBackend[Array[Byte], Array[Byte]] with
def remove(name: String): Boolean = {
- false
+ val mdata = getQueueMetadata(name)
+ mdata.getActiveIndexes foreach {
+ index =>
+ queueClient.delete(getIndexedKey(name, index))
+ }
+ queueClient.delete(getKey(name, queueHeadIndex))
+ queueClient.delete(getKey(name, queueTailIndex))
}
def peek(name: String, start: Int, count: Int): List[Array[Byte]] = {
@@ -236,15 +239,28 @@ MapStorageBackend[Array[Byte], Array[Byte]] with
}
def dequeue(name: String): Option[Array[Byte]] = {
- None
+ val mdata = getQueueMetadata(name)
+ if (mdata.canDequeue) {
+ val key = getIndexedKey(name, mdata.head)
+ val dequeued = queueClient.getValue(key)
+ queueClient.delete(key)
+ queueClient.put(getKey(name, queueHeadIndex), IntSerializer.toBytes(mdata.nextDequeue))
+ Some(dequeued)
+ } else {
+ None
+ }
}
def enqueue(name: String, item: Array[Byte]): Option[Int] = {
val mdata = getQueueMetadata(name)
- val key = getIndexedKey(name, mdata.tail)
- queueClient.put(key, item)
- queueClient.put(getKey(name, queueTailIndex), IntSerializer.toBytes(mdata.tail + 1))
- Some(mdata.size + 1)
+ if (mdata.canEnqueue) {
+ val key = getIndexedKey(name, mdata.tail)
+ queueClient.put(key, item)
+ queueClient.put(getKey(name, queueTailIndex), IntSerializer.toBytes(mdata.nextEnqueue))
+ Some(mdata.size + 1)
+ } else {
+ None
+ }
}
@@ -326,6 +342,50 @@ MapStorageBackend[Array[Byte], Array[Byte]] with
queueClient = storeClientFactory.getStoreClient(queueStore)
}
+
+ case class QueueMetadata(head: Int, tail: Int) {
+ //queue is an sequence with indexes from 0 to Int.MAX_VALUE
+ //wraps around when one pointer gets to max value
+ def size = {
+ if (tail >= head) {
+ tail - head
+ } else {
+ //queue has wrapped
+ Integer.MAX_VALUE - head + tail + 1
+ }
+ }
+
+ def canEnqueue = {
+ //the -1 stops the tail from catching the head on a wrap around
+ size < Integer.MAX_VALUE - 1
+ }
+
+ def canDequeue = {size > 0}
+
+ def getActiveIndexes(): Seq[Int] = {
+ if (tail >= head) {
+ head to tail
+ } else {
+ //queue has wrapped
+ (0 to tail) ++ (head to Integer.MAX_VALUE)
+ }
+ }
+
+ def nextEnqueue = {
+ tail match {
+ case Integer.MAX_VALUE => 0
+ case _ => tail + 1
+ }
+ }
+
+ def nextDequeue = {
+ head match {
+ case Integer.MAX_VALUE => 0
+ case _ => head + 1
+ }
+ }
+ }
+
object IntSerializer {
val bytesPerInt = java.lang.Integer.SIZE / java.lang.Byte.SIZE
diff --git a/akka-persistence/akka-persistence-voldemort/src/test/scala/VoldemortStorageBackendSuite.scala b/akka-persistence/akka-persistence-voldemort/src/test/scala/VoldemortStorageBackendSuite.scala
index 613181cbd2..d96e8520d2 100644
--- a/akka-persistence/akka-persistence-voldemort/src/test/scala/VoldemortStorageBackendSuite.scala
+++ b/akka-persistence/akka-persistence-voldemort/src/test/scala/VoldemortStorageBackendSuite.scala
@@ -8,6 +8,7 @@ import se.scalablesolutions.akka.persistence.voldemort.VoldemortStorageBackend._
import se.scalablesolutions.akka.util.{Logging}
import collection.immutable.TreeSet
import VoldemortStorageBackendSuite._
+import scala.None
@RunWith(classOf[JUnitRunner])
class VoldemortStorageBackendSuite extends FunSuite with ShouldMatchers with EmbeddedVoldemort with Logging {
@@ -126,6 +127,37 @@ class VoldemortStorageBackendSuite extends FunSuite with ShouldMatchers with Emb
}
+ test("Persistent Queue apis function as expected") {
+ val key = "queueApiKey"
+ val value = bytes("some bytes even")
+ val valueOdd = bytes("some bytes odd")
+ remove(key)
+ VoldemortStorageBackend.size(key) should be(0)
+ enqueue(key, value) should be(Some(1))
+ VoldemortStorageBackend.size(key) should be(1)
+ enqueue(key, valueOdd) should be(Some(2))
+ VoldemortStorageBackend.size(key) should be(2)
+ dequeue(key).get should be(value)
+ VoldemortStorageBackend.size(key) should be(1)
+ dequeue(key).get should be(valueOdd)
+ VoldemortStorageBackend.size(key) should be(0)
+ dequeue(key) should be(None)
+ queueClient.put(getKey(key, queueHeadIndex), IntSerializer.toBytes(Integer.MAX_VALUE))
+ queueClient.put(getKey(key, queueTailIndex), IntSerializer.toBytes(Integer.MAX_VALUE))
+ VoldemortStorageBackend.size(key) should be(0)
+ enqueue(key, value) should be(Some(1))
+ VoldemortStorageBackend.size(key) should be(1)
+ enqueue(key, valueOdd) should be(Some(2))
+ VoldemortStorageBackend.size(key) should be(2)
+ dequeue(key).get should be(value)
+ VoldemortStorageBackend.size(key) should be(1)
+ dequeue(key).get should be(valueOdd)
+ VoldemortStorageBackend.size(key) should be(0)
+ dequeue(key) should be(None)
+
+
+ }
+
}
object VoldemortStorageBackendSuite {
From 05adfd4b2d1d99c05dc8580a8ab0cf72a7ab17f0 Mon Sep 17 00:00:00 2001
From: David Greco
Date: Sat, 25 Sep 2010 09:09:52 +0200
Subject: [PATCH 18/82] Small change in the config file
---
config/akka-reference.conf | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/config/akka-reference.conf b/config/akka-reference.conf
index 4b510a960e..ee39d9ef22 100644
--- a/config/akka-reference.conf
+++ b/config/akka-reference.conf
@@ -167,7 +167,7 @@ akka {
}
hbase {
- zookeeper-quorum = "localhost" # A comma separated list of the hostnames or IP belonging to the zookeeper quorum
+ zookeeper-quorum = "localhost" # A comma separated list of hostnames or IPs of the zookeeper quorum instances
}
voldemort {
From eccfc868c9626e31c771a151c4356e17054ea336 Mon Sep 17 00:00:00 2001
From: ticktock
Date: Sat, 25 Sep 2010 12:05:06 -0400
Subject: [PATCH 19/82] Made dequeue operation retriable in case of errors,
switched from Seq to Stream for queue removal
---
.../main/scala/VoldemortStorageBackend.scala | 28 ++++++++++++++-----
1 file changed, 21 insertions(+), 7 deletions(-)
diff --git a/akka-persistence/akka-persistence-voldemort/src/main/scala/VoldemortStorageBackend.scala b/akka-persistence/akka-persistence-voldemort/src/main/scala/VoldemortStorageBackend.scala
index 7cfc24c092..0f36a0339d 100644
--- a/akka-persistence/akka-persistence-voldemort/src/main/scala/VoldemortStorageBackend.scala
+++ b/akka-persistence/akka-persistence-voldemort/src/main/scala/VoldemortStorageBackend.scala
@@ -21,6 +21,11 @@ import collection.immutable.{IndexedSeq, SortedSet, TreeSet, HashMap}
import collection.mutable.{Set, HashSet, ArrayBuffer}
import java.util.{Properties, Map => JMap}
+/*
+ RequiredReads + RequiredWrites should be > ReplicationFactor for all Voldemort Stores
+ In this case all VoldemortBackend operations can be retried until successful, and data should remain consistent
+ */
+
private[akka] object VoldemortStorageBackend extends
MapStorageBackend[Array[Byte], Array[Byte]] with
VectorStorageBackend[Array[Byte]] with
@@ -242,10 +247,19 @@ MapStorageBackend[Array[Byte], Array[Byte]] with
val mdata = getQueueMetadata(name)
if (mdata.canDequeue) {
val key = getIndexedKey(name, mdata.head)
- val dequeued = queueClient.getValue(key)
- queueClient.delete(key)
- queueClient.put(getKey(name, queueHeadIndex), IntSerializer.toBytes(mdata.nextDequeue))
- Some(dequeued)
+ try {
+ val dequeued = queueClient.getValue(key)
+ queueClient.put(getKey(name, queueHeadIndex), IntSerializer.toBytes(mdata.nextDequeue))
+ Some(dequeued)
+ }
+ finally {
+ try {
+ queueClient.delete(key)
+ } catch {
+ //a failure to delete is ok, just leaves a K-V in Voldemort that will be overwritten if the queue ever wraps around
+ case e: Exception => log.warn(e, "caught an exception while deleting a dequeued element, however this will not cause any inconsistency in the queue")
+ }
+ }
} else {
None
}
@@ -362,12 +376,12 @@ MapStorageBackend[Array[Byte], Array[Byte]] with
def canDequeue = {size > 0}
- def getActiveIndexes(): Seq[Int] = {
+ def getActiveIndexes(): Stream[Int] = {
if (tail >= head) {
- head to tail
+ Stream.range(head, tail)
} else {
//queue has wrapped
- (0 to tail) ++ (head to Integer.MAX_VALUE)
+ Stream.range(0, tail) ++ Stream.range(head, Integer.MAX_VALUE)
}
}
From 3fe641f2e41b8cae4517217e5ec3890d1472b885 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jonas=20Bon=C3=A9r?=
Date: Mon, 27 Sep 2010 11:59:28 +0200
Subject: [PATCH 20/82] Support for more durable mailboxes
---
.../ExecutorBasedEventDrivenDispatcher.scala | 2 +-
.../main/scala/dispatch/HawtDispatcher.scala | 2 ++
.../main/scala/dispatch/MailboxHandling.scala | 8 ++---
.../main/scala/dispatch/MessageHandling.scala | 2 ++
.../scala/dispatch/ThreadPoolBuilder.scala | 2 ++
.../main/scala/util/ReflectiveAccess.scala | 29 ++++++++++++++-----
.../src/main/protocol/RemoteProtocol.proto | 2 +-
.../serialization/SerializationProtocol.scala | 10 +++++--
8 files changed, 40 insertions(+), 17 deletions(-)
diff --git a/akka-actor/src/main/scala/dispatch/ExecutorBasedEventDrivenDispatcher.scala b/akka-actor/src/main/scala/dispatch/ExecutorBasedEventDrivenDispatcher.scala
index de4512c094..f40261cddb 100644
--- a/akka-actor/src/main/scala/dispatch/ExecutorBasedEventDrivenDispatcher.scala
+++ b/akka-actor/src/main/scala/dispatch/ExecutorBasedEventDrivenDispatcher.scala
@@ -135,7 +135,7 @@ class ExecutorBasedEventDrivenDispatcher(
registerForExecution(mbox)
}
- protected def registerForExecution(mailbox: MessageQueue with ExecutableMailbox): Unit = if (active) {
+ def registerForExecution(mailbox: MessageQueue with ExecutableMailbox): Unit = if (active) {
if (mailbox.dispatcherLock.tryLock()) {
try {
executor execute mailbox
diff --git a/akka-actor/src/main/scala/dispatch/HawtDispatcher.scala b/akka-actor/src/main/scala/dispatch/HawtDispatcher.scala
index 006ae6e843..549765d9fe 100644
--- a/akka-actor/src/main/scala/dispatch/HawtDispatcher.scala
+++ b/akka-actor/src/main/scala/dispatch/HawtDispatcher.scala
@@ -147,6 +147,8 @@ class HawtDispatcher(val aggregate: Boolean = true, val parent: DispatchQueue =
def start = if (active.compareAndSet(false, true)) retainNonDaemon
+ def execute(task: Runnable) {}
+
def shutdown = if (active.compareAndSet(true, false)) releaseNonDaemon
def isShutdown = !active.get
diff --git a/akka-actor/src/main/scala/dispatch/MailboxHandling.scala b/akka-actor/src/main/scala/dispatch/MailboxHandling.scala
index fe84e04ff2..360c8a143f 100644
--- a/akka-actor/src/main/scala/dispatch/MailboxHandling.scala
+++ b/akka-actor/src/main/scala/dispatch/MailboxHandling.scala
@@ -105,10 +105,10 @@ trait MailboxFactory {
*/
protected def createDurableMailbox(actorRef: ActorRef, mailboxType: DurableMailboxType): AnyRef = mailboxType match {
// FIXME make generic (work for TypedActor as well)
- case FileBasedDurableMailbox(serializer) => EnterpriseModule.createFileBasedMailbox(actorRef.uuid, ActorType.ScalaActor, None).asInstanceOf[MessageQueue]
- case RedisBasedDurableMailbox(serializer) => throw new UnsupportedOperationException("RedisBasedDurableMailbox is not yet supported")
- case BeanstalkBasedDurableMailbox(serializer) => throw new UnsupportedOperationException("BeanstalkBasedDurableMailbox is not yet supported")
- case ZooKeeperBasedDurableMailbox(serializer) => throw new UnsupportedOperationException("ZooKeeperBasedDurableMailbox is not yet supported")
+ case FileBasedDurableMailbox(serializer) => EnterpriseModule.createFileBasedMailbox(actorRef).asInstanceOf[MessageQueue]
+ case ZooKeeperBasedDurableMailbox(serializer) => EnterpriseModule.createZooKeeperBasedMailbox(actorRef).asInstanceOf[MessageQueue]
+ case BeanstalkBasedDurableMailbox(serializer) => EnterpriseModule.createBeanstalkBasedMailbox(actorRef).asInstanceOf[MessageQueue]
+ case RedisBasedDurableMailbox(serializer) => EnterpriseModule.createRedisBasedMailbox(actorRef).asInstanceOf[MessageQueue]
case AMQPBasedDurableMailbox(serializer) => throw new UnsupportedOperationException("AMQPBasedDurableMailbox is not yet supported")
case JMSBasedDurableMailbox(serializer) => throw new UnsupportedOperationException("JMSBasedDurableMailbox is not yet supported")
}
diff --git a/akka-actor/src/main/scala/dispatch/MessageHandling.scala b/akka-actor/src/main/scala/dispatch/MessageHandling.scala
index 06516e52d4..d2ff59854a 100644
--- a/akka-actor/src/main/scala/dispatch/MessageHandling.scala
+++ b/akka-actor/src/main/scala/dispatch/MessageHandling.scala
@@ -65,6 +65,8 @@ trait MessageDispatcher extends MailboxFactory with Logging {
def dispatch(invocation: MessageInvocation): Unit
+ def execute(task: Runnable): Unit
+
def start: Unit
def shutdown: Unit
diff --git a/akka-actor/src/main/scala/dispatch/ThreadPoolBuilder.scala b/akka-actor/src/main/scala/dispatch/ThreadPoolBuilder.scala
index 5ad1b89aca..7559785dcf 100644
--- a/akka-actor/src/main/scala/dispatch/ThreadPoolBuilder.scala
+++ b/akka-actor/src/main/scala/dispatch/ThreadPoolBuilder.scala
@@ -30,6 +30,8 @@ trait ThreadPoolBuilder extends Logging {
protected var executor: ExecutorService = _
+ def execute(task: Runnable) = executor execute task
+
def isShutdown = executor.isShutdown
def buildThreadPool(): Unit = synchronized {
diff --git a/akka-actor/src/main/scala/util/ReflectiveAccess.scala b/akka-actor/src/main/scala/util/ReflectiveAccess.scala
index 6a719d3834..d0824941ce 100644
--- a/akka-actor/src/main/scala/util/ReflectiveAccess.scala
+++ b/akka-actor/src/main/scala/util/ReflectiveAccess.scala
@@ -201,7 +201,7 @@ object ReflectiveAccess extends Logging {
object EnterpriseModule {
- type FileBasedMailbox = {
+ type Mailbox = {
def enqueue(message: MessageInvocation)
def dequeue: MessageInvocation
}
@@ -222,16 +222,23 @@ object ReflectiveAccess extends Logging {
def ensureEnterpriseEnabled = if (!isEnterpriseEnabled) throw new ModuleNotAvailableException(
"Feature is only available in Akka Enterprise")
- def createFileBasedMailbox(
- uuid: Uuid, actorType: ActorType, typedActorInfo: Option[Tuple2[String, String]]): FileBasedMailbox = {
+ def createFileBasedMailbox(actorRef: ActorRef): Mailbox = createMailbox("se.scalablesolutions.akka.cluster.FileBasedMailbox", actorRef)
+
+ def createZooKeeperBasedMailbox(actorRef: ActorRef): Mailbox = createMailbox("se.scalablesolutions.akka.cluster.ZooKeeperBasedMailbox", actorRef)
+
+ def createBeanstalkBasedMailbox(actorRef: ActorRef): Mailbox = createMailbox("se.scalablesolutions.akka.cluster.BeanstalkBasedMailbox", actorRef)
+
+ def createRedisBasedMailbox(actorRef: ActorRef): Mailbox = createMailbox("se.scalablesolutions.akka.cluster.RedisBasedMailbox", actorRef)
+
+ private def createMailbox(mailboxClassname: String, actorRef: ActorRef): Mailbox = {
ensureEnterpriseEnabled
createInstance(
- "se.scalablesolutions.akka.cluster.FileBasedMailbox",
- Array(classOf[Uuid], classOf[ActorType], classOf[Option[Tuple2[String, String]]]),
- Array(uuid, actorType, typedActorInfo).asInstanceOf[Array[AnyRef]],
+ mailboxClassname,
+ Array(classOf[ActorRef]),
+ Array(actorRef).asInstanceOf[Array[AnyRef]],
loader)
- .getOrElse(throw new IllegalActorStateException("Could not create file-based mailbox"))
- .asInstanceOf[FileBasedMailbox]
+ .getOrElse(throw new IllegalActorStateException("Could not create durable mailbox [" + mailboxClassname + "] for actor [" + actorRef + "]"))
+ .asInstanceOf[Mailbox]
}
}
@@ -249,9 +256,11 @@ object ReflectiveAccess extends Logging {
Some(ctor.newInstance(args: _*).asInstanceOf[T])
} catch {
case e: java.lang.reflect.InvocationTargetException =>
+ e.printStackTrace
log.error(e.getCause, "Could not instantiate class [%s]", clazz.getName)
None
case e: Exception =>
+ e.printStackTrace
log.error(e.getCause, "Could not instantiate class [%s]", clazz.getName)
None
}
@@ -269,9 +278,11 @@ object ReflectiveAccess extends Logging {
Some(ctor.newInstance(args: _*).asInstanceOf[T])
} catch {
case e: java.lang.reflect.InvocationTargetException =>
+ e.printStackTrace
log.error(e.getCause, "Could not instantiate class [%s] due to [%s]", fqn, e.toString)
None
case e: Exception =>
+ e.printStackTrace
log.error(e.getCause, "Could not instantiate class [%s] due to [%s]", fqn, e.toString)
None
}
@@ -284,9 +295,11 @@ object ReflectiveAccess extends Logging {
Option(instance.get(null).asInstanceOf[T])
} catch {
case e: java.lang.reflect.InvocationTargetException =>
+ e.printStackTrace
log.error(e.getCause, "Could not instantiate class [%s]", fqn)
None
case e: Exception =>
+ e.printStackTrace
log.error(e.getCause, "Could not instantiate class [%s]", fqn)
None
}
diff --git a/akka-remote/src/main/protocol/RemoteProtocol.proto b/akka-remote/src/main/protocol/RemoteProtocol.proto
index 1ea9d8f986..40c5756e04 100644
--- a/akka-remote/src/main/protocol/RemoteProtocol.proto
+++ b/akka-remote/src/main/protocol/RemoteProtocol.proto
@@ -23,7 +23,7 @@ message RemoteActorRefProtocol {
}
/**
- * Defines a remote ActorRef that "remembers" and uses its original typed Actor instance
+ * Defines a remote Typed ActorRef that "remembers" and uses its original typed Actor instance
* on the original node.
*/
message RemoteTypedActorRefProtocol {
diff --git a/akka-remote/src/main/scala/serialization/SerializationProtocol.scala b/akka-remote/src/main/scala/serialization/SerializationProtocol.scala
index c07417c0e2..2482e15b05 100644
--- a/akka-remote/src/main/scala/serialization/SerializationProtocol.scala
+++ b/akka-remote/src/main/scala/serialization/SerializationProtocol.scala
@@ -192,7 +192,7 @@ object ActorSerialization {
}
val ar = new LocalActorRef(
- uuidFrom(protocol.getUuid.getHigh,protocol.getUuid.getLow),
+ uuidFrom(protocol.getUuid.getHigh, protocol.getUuid.getLow),
protocol.getId,
protocol.getOriginalAddress.getHostname,
protocol.getOriginalAddress.getPort,
@@ -231,7 +231,7 @@ object RemoteActorSerialization {
* Deserializes a RemoteActorRefProtocol Protocol Buffers (protobuf) Message into an RemoteActorRef instance.
*/
private[akka] def fromProtobufToRemoteActorRef(protocol: RemoteActorRefProtocol, loader: Option[ClassLoader]): ActorRef = {
- Actor.log.debug("Deserializing RemoteActorRefProtocol to RemoteActorRef:\n" + protocol)
+ Actor.log.debug("Deserializing RemoteActorRefProtocol to RemoteActorRef:\n %s", protocol)
RemoteActorRef(
protocol.getClassOrServiceName,
protocol.getActorClassname,
@@ -299,7 +299,11 @@ object RemoteActorSerialization {
.setIsOneWay(isOneWay)
val id = registerSupervisorAsRemoteActor
- if (id.isDefined) requestBuilder.setSupervisorUuid(UuidProtocol.newBuilder.setHigh(id.get.getTime).setLow(id.get.getClockSeqAndNode).build)
+ if (id.isDefined) requestBuilder.setSupervisorUuid(
+ UuidProtocol.newBuilder
+ .setHigh(id.get.getTime)
+ .setLow(id.get.getClockSeqAndNode)
+ .build)
senderOption.foreach { sender =>
RemoteServer.getOrCreateServer(sender.homeAddress).register(sender.uuid.toString, sender)
From fc77a138e71923d0af9ea631f993f03669dc2aa8 Mon Sep 17 00:00:00 2001
From: Viktor Klang
Date: Mon, 27 Sep 2010 17:30:49 +0200
Subject: [PATCH 21/82] Fixing ticket 413
---
.../ExecutorBasedEventDrivenDispatcher.scala | 4 ++++
...orBasedEventDrivenWorkStealingDispatcher.scala | 15 +++++++++------
2 files changed, 13 insertions(+), 6 deletions(-)
diff --git a/akka-actor/src/main/scala/dispatch/ExecutorBasedEventDrivenDispatcher.scala b/akka-actor/src/main/scala/dispatch/ExecutorBasedEventDrivenDispatcher.scala
index de4512c094..aa525adb92 100644
--- a/akka-actor/src/main/scala/dispatch/ExecutorBasedEventDrivenDispatcher.scala
+++ b/akka-actor/src/main/scala/dispatch/ExecutorBasedEventDrivenDispatcher.scala
@@ -116,6 +116,10 @@ class ExecutorBasedEventDrivenDispatcher(
val started = if (isDeadlineEnabled) System.currentTimeMillis else 0
do {
nextMessage.invoke
+
+ if (nextMessage.receiver.isBeingRestarted)
+ return !self.isEmpty
+
if (throttle) { // Will be elided when false
processedMessages += 1
if ((processedMessages >= throughput) ||
diff --git a/akka-actor/src/main/scala/dispatch/ExecutorBasedEventDrivenWorkStealingDispatcher.scala b/akka-actor/src/main/scala/dispatch/ExecutorBasedEventDrivenWorkStealingDispatcher.scala
index faefa4fd10..a5ed113b97 100644
--- a/akka-actor/src/main/scala/dispatch/ExecutorBasedEventDrivenWorkStealingDispatcher.scala
+++ b/akka-actor/src/main/scala/dispatch/ExecutorBasedEventDrivenWorkStealingDispatcher.scala
@@ -75,33 +75,36 @@ class ExecutorBasedEventDrivenWorkStealingDispatcher(
* @return true if the mailbox was processed, false otherwise
*/
private def tryProcessMailbox(mailbox: MessageQueue): Boolean = {
- var lockAcquiredOnce = false
+ var mailboxWasProcessed = false
// this do-wile loop is required to prevent missing new messages between the end of processing
// the mailbox and releasing the lock
do {
if (mailbox.dispatcherLock.tryLock) {
- lockAcquiredOnce = true
try {
- processMailbox(mailbox)
+ mailboxWasProcessed = processMailbox(mailbox)
} finally {
mailbox.dispatcherLock.unlock
}
}
- } while ((lockAcquiredOnce && !mailbox.isEmpty))
+ } while ((mailboxWasProcessed && !mailbox.isEmpty))
- lockAcquiredOnce
+ mailboxWasProcessed
}
/**
* Process the messages in the mailbox of the given actor.
+ * @return
*/
- private def processMailbox(mailbox: MessageQueue) = {
+ private def processMailbox(mailbox: MessageQueue): Boolean = {
var messageInvocation = mailbox.dequeue
while (messageInvocation ne null) {
messageInvocation.invoke
+ if (messageInvocation.receiver.isBeingRestarted)
+ return false
messageInvocation = mailbox.dequeue
}
+ true
}
private def findThief(receiver: ActorRef): Option[ActorRef] = {
From 9856f169004ea49fc491ad959f0c08ca35ec65d7 Mon Sep 17 00:00:00 2001
From: ticktock
Date: Mon, 27 Sep 2010 16:59:44 -0400
Subject: [PATCH 22/82] Further Queue Impl
---
.../main/scala/VoldemortStorageBackend.scala | 27 +++++++++++++++----
.../scala/VoldemortStorageBackendSuite.scala | 7 +++++
2 files changed, 29 insertions(+), 5 deletions(-)
diff --git a/akka-persistence/akka-persistence-voldemort/src/main/scala/VoldemortStorageBackend.scala b/akka-persistence/akka-persistence-voldemort/src/main/scala/VoldemortStorageBackend.scala
index 0f36a0339d..92d8d4a2d2 100644
--- a/akka-persistence/akka-persistence-voldemort/src/main/scala/VoldemortStorageBackend.scala
+++ b/akka-persistence/akka-persistence-voldemort/src/main/scala/VoldemortStorageBackend.scala
@@ -236,7 +236,14 @@ MapStorageBackend[Array[Byte], Array[Byte]] with
}
def peek(name: String, start: Int, count: Int): List[Array[Byte]] = {
- List(Array.empty[Byte])
+ val mdata = getQueueMetadata(name)
+ val ret = mdata.getPeekIndexes(start, count).toList map {
+ index: Int => {
+ log.debug("peeking:" + index)
+ queueClient.getValue(getIndexedKey(name, index))
+ }
+ }
+ ret
}
def size(name: String): Int = {
@@ -360,12 +367,14 @@ MapStorageBackend[Array[Byte], Array[Byte]] with
case class QueueMetadata(head: Int, tail: Int) {
//queue is an sequence with indexes from 0 to Int.MAX_VALUE
//wraps around when one pointer gets to max value
+ //head has an element in it.
+ //tail is the next slot to write to.
def size = {
if (tail >= head) {
tail - head
} else {
//queue has wrapped
- Integer.MAX_VALUE - head + tail + 1
+ (Integer.MAX_VALUE - head) + (tail + 1)
}
}
@@ -376,15 +385,23 @@ MapStorageBackend[Array[Byte], Array[Byte]] with
def canDequeue = {size > 0}
- def getActiveIndexes(): Stream[Int] = {
+ def getActiveIndexes(): IndexedSeq[Int] = {
if (tail >= head) {
- Stream.range(head, tail)
+ Range(head, tail)
} else {
//queue has wrapped
- Stream.range(0, tail) ++ Stream.range(head, Integer.MAX_VALUE)
+ val headRange = Range(head, Integer.MAX_VALUE)
+ (if (tail > 0) {headRange ++ Range(0, tail - 1)} else {headRange})
}
}
+ def getPeekIndexes(start: Int, count: Int): IndexedSeq[Int] = {
+ val indexes = getActiveIndexes
+ if (indexes.size < start)
+ {IndexedSeq.empty[Int]} else
+ {indexes.drop(start).take(count)}
+ }
+
def nextEnqueue = {
tail match {
case Integer.MAX_VALUE => 0
diff --git a/akka-persistence/akka-persistence-voldemort/src/test/scala/VoldemortStorageBackendSuite.scala b/akka-persistence/akka-persistence-voldemort/src/test/scala/VoldemortStorageBackendSuite.scala
index d96e8520d2..8ac3d306c4 100644
--- a/akka-persistence/akka-persistence-voldemort/src/test/scala/VoldemortStorageBackendSuite.scala
+++ b/akka-persistence/akka-persistence-voldemort/src/test/scala/VoldemortStorageBackendSuite.scala
@@ -131,12 +131,15 @@ class VoldemortStorageBackendSuite extends FunSuite with ShouldMatchers with Emb
val key = "queueApiKey"
val value = bytes("some bytes even")
val valueOdd = bytes("some bytes odd")
+
remove(key)
VoldemortStorageBackend.size(key) should be(0)
enqueue(key, value) should be(Some(1))
VoldemortStorageBackend.size(key) should be(1)
enqueue(key, valueOdd) should be(Some(2))
VoldemortStorageBackend.size(key) should be(2)
+ peek(key, 0, 1)(0) should be(value)
+ peek(key, 1, 1)(0) should be(valueOdd)
dequeue(key).get should be(value)
VoldemortStorageBackend.size(key) should be(1)
dequeue(key).get should be(valueOdd)
@@ -149,6 +152,8 @@ class VoldemortStorageBackendSuite extends FunSuite with ShouldMatchers with Emb
VoldemortStorageBackend.size(key) should be(1)
enqueue(key, valueOdd) should be(Some(2))
VoldemortStorageBackend.size(key) should be(2)
+ peek(key, 0, 1)(0) should be(value)
+ peek(key, 1, 1)(0) should be(valueOdd)
dequeue(key).get should be(value)
VoldemortStorageBackend.size(key) should be(1)
dequeue(key).get should be(valueOdd)
@@ -158,6 +163,8 @@ class VoldemortStorageBackendSuite extends FunSuite with ShouldMatchers with Emb
}
+
+
}
object VoldemortStorageBackendSuite {
From ff04da0b24d3ded2f595de84ee34524553a32faf Mon Sep 17 00:00:00 2001
From: ticktock
Date: Mon, 27 Sep 2010 19:05:35 -0400
Subject: [PATCH 23/82] Finished off Queue API
---
.../src/main/scala/VoldemortStorageBackend.scala | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/akka-persistence/akka-persistence-voldemort/src/main/scala/VoldemortStorageBackend.scala b/akka-persistence/akka-persistence-voldemort/src/main/scala/VoldemortStorageBackend.scala
index 92d8d4a2d2..9883eb121f 100644
--- a/akka-persistence/akka-persistence-voldemort/src/main/scala/VoldemortStorageBackend.scala
+++ b/akka-persistence/akka-persistence-voldemort/src/main/scala/VoldemortStorageBackend.scala
@@ -390,8 +390,8 @@ MapStorageBackend[Array[Byte], Array[Byte]] with
Range(head, tail)
} else {
//queue has wrapped
- val headRange = Range(head, Integer.MAX_VALUE)
- (if (tail > 0) {headRange ++ Range(0, tail - 1)} else {headRange})
+ val headRange = Range.inclusive(head, Integer.MAX_VALUE)
+ (if (tail > 0) {headRange ++ Range(0, tail)} else {headRange})
}
}
From 39c732c785385e5ecc04735fcf4923d9afa5c280 Mon Sep 17 00:00:00 2001
From: ticktock
Date: Mon, 27 Sep 2010 20:23:05 -0400
Subject: [PATCH 24/82] Initial PersistentRef spec
---
.../test/scala/RefStorageBackendTest.scala | 49 +++++++++++++++++++
...emortStorageBackendCompatibilityTest.scala | 16 ++++++
2 files changed, 65 insertions(+)
create mode 100644 akka-persistence/akka-persistence-common/src/test/scala/RefStorageBackendTest.scala
create mode 100644 akka-persistence/akka-persistence-voldemort/src/test/scala/VoldemortStorageBackendCompatibilityTest.scala
diff --git a/akka-persistence/akka-persistence-common/src/test/scala/RefStorageBackendTest.scala b/akka-persistence/akka-persistence-common/src/test/scala/RefStorageBackendTest.scala
new file mode 100644
index 0000000000..9625f45ebd
--- /dev/null
+++ b/akka-persistence/akka-persistence-common/src/test/scala/RefStorageBackendTest.scala
@@ -0,0 +1,49 @@
+/**
+ * Copyright (C) 2009-2010 Scalable Solutions AB
+ */
+
+package se.scalablesolutions.akka.persistence.common
+
+import org.scalatest.junit.JUnitRunner
+import org.junit.runner.RunWith
+import org.scalatest.matchers.ShouldMatchers
+import se.scalablesolutions.akka.util.Logging
+import org.scalatest.{Suite, BeforeAndAfterEach, Spec}
+
+/**
+ * Implementation Compatibility test for PersistentRef backend implementations.
+ */
+@RunWith(classOf[JUnitRunner])
+trait RefStorageBackendTest extends Spec with ShouldMatchers with BeforeAndAfterEach with Logging {
+ this: Spec =>
+ def storage: RefStorageBackend[Array[Byte]]
+
+ def dropRefs: Unit
+
+ override def beforeEach = {
+ log.info("beforeEach: dropping refs")
+ dropRefs
+ }
+
+ override def afterEach = {
+ log.info("afterEach: dropping refs")
+ dropRefs
+ }
+
+
+ describe("A Properly functioning RefStorage Backend") {
+ it("should successfully insert ref storage") {
+ val name = "RefStorageTest #1"
+ val value = name.getBytes
+ storage.insertRefStorageFor(name, value)
+ storage.getRefStorageFor(name).get should be(value)
+ }
+
+ it("should return None when getRefStorage is called when no value has been inserted") {
+ val name = "RefStorageTest #2"
+ val value = name.getBytes
+ storage.getRefStorageFor(name) should be(None)
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/akka-persistence/akka-persistence-voldemort/src/test/scala/VoldemortStorageBackendCompatibilityTest.scala b/akka-persistence/akka-persistence-voldemort/src/test/scala/VoldemortStorageBackendCompatibilityTest.scala
new file mode 100644
index 0000000000..095927e8ae
--- /dev/null
+++ b/akka-persistence/akka-persistence-voldemort/src/test/scala/VoldemortStorageBackendCompatibilityTest.scala
@@ -0,0 +1,16 @@
+package se.scalablesolutions.akka.persistence.voldemort
+
+
+import org.junit.runner.RunWith
+import org.scalatest.junit.JUnitRunner
+import se.scalablesolutions.akka.persistence.common.{RefStorageBackend, RefStorageBackendTest}
+import org.scalatest.Spec
+
+
+@RunWith(classOf[JUnitRunner])
+class VoldemortStorageBackendCompatibilityTest extends RefStorageBackendTest with EmbeddedVoldemort {
+ def dropRefs: Unit = {}
+
+
+ def storage: RefStorageBackend[Array[Byte]] = {VoldemortStorageBackend}
+}
\ No newline at end of file
From 0cc2e26a91d18c73ec20a65b34e8baf4c7731fbf Mon Sep 17 00:00:00 2001
From: Viktor Klang
Date: Tue, 28 Sep 2010 10:22:55 +0200
Subject: [PATCH 25/82] Fixing compiler issue that caused problems when
compiling with JDT
---
.../src/main/scala/Storage.scala | 47 ++++++++++++-------
1 file changed, 31 insertions(+), 16 deletions(-)
diff --git a/akka-persistence/akka-persistence-common/src/main/scala/Storage.scala b/akka-persistence/akka-persistence-common/src/main/scala/Storage.scala
index 088c0b8ff4..77e40a6127 100644
--- a/akka-persistence/akka-persistence-common/src/main/scala/Storage.scala
+++ b/akka-persistence/akka-persistence-common/src/main/scala/Storage.scala
@@ -71,6 +71,16 @@ trait Storage {
throw new UnsupportedOperationException
}
+private[akka] object PersistentMap {
+ // operations on the Map
+ sealed trait Op
+ case object GET extends Op
+ case object PUT extends Op
+ case object REM extends Op
+ case object UPD extends Op
+ case object CLR extends Op
+}
+
/**
* Implementation of PersistentMap for every concrete
* storage will have the same workflow. This abstracts the workflow.
@@ -83,13 +93,8 @@ trait Storage {
trait PersistentMap[K, V] extends scala.collection.mutable.Map[K, V]
with Transactional with Committable with Abortable with Logging {
- // operations on the Map
- trait Op
- case object GET extends Op
- case object PUT extends Op
- case object REM extends Op
- case object UPD extends Op
- case object CLR extends Op
+ //Import Ops
+ import PersistentMap._
// append only log: records all mutating operations
protected val appendOnlyTxLog = TransactionalVector[LogEntry]()
@@ -362,17 +367,22 @@ trait PersistentMapBinary extends PersistentMap[Array[Byte], Array[Byte]] {
}
}
+private[akka] object PersistentVector {
+ // operations on the Vector
+ sealed trait Op
+ case object ADD extends Op
+ case object UPD extends Op
+ case object POP extends Op
+}
+
/**
* Implements a template for a concrete persistent transactional vector based storage.
*
* @author Jonas Bonér
*/
trait PersistentVector[T] extends IndexedSeq[T] with Transactional with Committable with Abortable {
- // operations on the Vector
- trait Op
- case object ADD extends Op
- case object UPD extends Op
- case object POP extends Op
+ //Import Ops
+ import PersistentVector._
// append only log: records all mutating operations
protected val appendOnlyTxLog = TransactionalVector[LogEntry]()
@@ -510,6 +520,13 @@ trait PersistentRef[T] extends Transactional with Committable with Abortable {
}
}
+ private[akka] object PersistentQueue {
+ //Operations for PersistentQueue
+ sealed trait QueueOp
+ case object ENQ extends QueueOp
+ case object DEQ extends QueueOp
+ }
+
/**
* Implementation of PersistentQueue for every concrete
* storage will have the same workflow. This abstracts the workflow.
@@ -538,10 +555,8 @@ trait PersistentRef[T] extends Transactional with Committable with Abortable {
trait PersistentQueue[A] extends scala.collection.mutable.Queue[A]
with Transactional with Committable with Abortable with Logging {
- sealed trait QueueOp
- case object ENQ extends QueueOp
- case object DEQ extends QueueOp
-
+ //Import Ops
+ import PersistentQueue._
import scala.collection.immutable.Queue
// current trail that will be played on commit to the underlying store
From 2e9d87364acab472c33b06efae9be93142a430df Mon Sep 17 00:00:00 2001
From: Michael Kober
Date: Tue, 28 Sep 2010 11:12:40 +0200
Subject: [PATCH 26/82] closing ticket441, implemented typed actor methods for
ActorRegistry
---
.../src/main/scala/actor/ActorRegistry.scala | 135 +++++++++++++++++-
.../main/scala/util/ReflectiveAccess.scala | 3 +
.../src/main/scala/actor/TypedActor.scala | 13 +-
.../actor/typed-actor/TypedActorSpec.scala | 124 +++++++++++++++-
4 files changed, 266 insertions(+), 9 deletions(-)
diff --git a/akka-actor/src/main/scala/actor/ActorRegistry.scala b/akka-actor/src/main/scala/actor/ActorRegistry.scala
index e425451470..4099d64160 100644
--- a/akka-actor/src/main/scala/actor/ActorRegistry.scala
+++ b/akka-actor/src/main/scala/actor/ActorRegistry.scala
@@ -10,8 +10,9 @@ import scala.reflect.Manifest
import java.util.concurrent.{ConcurrentSkipListSet, ConcurrentHashMap}
import java.util.{Set => JSet}
-import se.scalablesolutions.akka.util.ListenerManagement
import annotation.tailrec
+import se.scalablesolutions.akka.util.ListenerManagement
+import se.scalablesolutions.akka.util.ReflectiveAccess._
/**
* Base trait for ActorRegistry events, allows listen to when an actor is added and removed from the ActorRegistry.
@@ -109,11 +110,126 @@ object ActorRegistry extends ListenerManagement {
*/
def actorsFor(id: String): Array[ActorRef] = actorsById values id
- /**
+ /**
* Finds the actor that has a specific UUID.
*/
def actorFor(uuid: Uuid): Option[ActorRef] = Option(actorsByUUID get uuid)
+ /**
+ * Returns all typed actors in the system.
+ */
+ def typedActors: Array[AnyRef] = filterTypedActors(_ => true)
+
+ /**
+ * Invokes a function for all typed actors.
+ */
+ def foreachTypedActor(f: (AnyRef) => Unit) = {
+ val elements = actorsByUUID.elements
+ while (elements.hasMoreElements) {
+ val proxy = typedActorFor(elements.nextElement)
+ if (proxy.isDefined) {
+ f(proxy.get)
+ }
+ }
+ }
+
+ /**
+ * Invokes the function on all known typed actors until it returns Some
+ * Returns None if the function never returns Some
+ */
+ def findTypedActor[T](f: PartialFunction[AnyRef,T]) : Option[T] = {
+ val elements = actorsByUUID.elements
+ while (elements.hasMoreElements) {
+ val proxy = typedActorFor(elements.nextElement)
+ if(proxy.isDefined && (f isDefinedAt proxy))
+ return Some(f(proxy))
+ }
+ None
+ }
+
+ /**
+ * Finds all typed actors that satisfy a predicate.
+ */
+ def filterTypedActors(p: AnyRef => Boolean): Array[AnyRef] = {
+ TypedActorModule.ensureTypedActorEnabled
+ val all = new ListBuffer[AnyRef]
+ val elements = actorsByUUID.elements
+ while (elements.hasMoreElements) {
+ val proxy = typedActorFor(elements.nextElement)
+ if (proxy.isDefined && p(proxy.get)) {
+ all += proxy.get
+ }
+ }
+ all.toArray
+ }
+
+ /**
+ * Finds all typed actors that are subtypes of the class passed in as the Manifest argument.
+ */
+ def typedActorsFor[T <: AnyRef](implicit manifest: Manifest[T]): Array[AnyRef] = {
+ TypedActorModule.ensureTypedActorEnabled
+ typedActorsFor[T](manifest.erasure.asInstanceOf[Class[T]])
+ }
+
+ /**
+ * Finds any typed actor that matches T.
+ */
+ def typedActorFor[T <: AnyRef](implicit manifest: Manifest[T]): Option[AnyRef] = {
+ def predicate(proxy: AnyRef) : Boolean = {
+ val actorRef = actorFor(proxy)
+ actorRef.isDefined && manifest.erasure.isAssignableFrom(actorRef.get.actor.getClass)
+ }
+ findTypedActor({ case a:AnyRef if predicate(a) => a })
+ }
+
+ /**
+ * Finds all typed actors of type or sub-type specified by the class passed in as the Class argument.
+ */
+ def typedActorsFor[T <: AnyRef](clazz: Class[T]): Array[AnyRef] = {
+ TypedActorModule.ensureTypedActorEnabled
+ def predicate(proxy: AnyRef) : Boolean = {
+ val actorRef = actorFor(proxy)
+ actorRef.isDefined && clazz.isAssignableFrom(actorRef.get.actor.getClass)
+ }
+ filterTypedActors(predicate)
+ }
+
+ /**
+ * Finds all typed actors that have a specific id.
+ */
+ def typedActorsFor(id: String): Array[AnyRef] = {
+ TypedActorModule.ensureTypedActorEnabled
+ val actorRefs = actorsById values id
+ actorRefs.flatMap(typedActorFor(_))
+ }
+
+ /**
+ * Finds the typed actor that has a specific UUID.
+ */
+ def typedActorFor(uuid: Uuid): Option[AnyRef] = {
+ TypedActorModule.ensureTypedActorEnabled
+ val actorRef = actorsByUUID get uuid
+ if (actorRef eq null)
+ None
+ else
+ typedActorFor(actorRef)
+ }
+
+ /**
+ * Get the typed actor proxy for a given typed actor ref.
+ */
+ private def typedActorFor(actorRef: ActorRef): Option[AnyRef] = {
+ TypedActorModule.typedActorObjectInstance.get.proxyFor(actorRef)
+ }
+
+ /**
+ * Get the underlying typed actor for a given proxy.
+ */
+ private def actorFor(proxy: AnyRef): Option[ActorRef] = {
+ TypedActorModule.typedActorObjectInstance.get.actorFor(proxy)
+ }
+
+
/**
* Registers an actor in the ActorRegistry.
*/
@@ -145,7 +261,20 @@ object ActorRegistry extends ListenerManagement {
*/
def shutdownAll() {
log.info("Shutting down all actors in the system...")
- foreach(_.stop)
+ if (TypedActorModule.isTypedActorEnabled) {
+ val elements = actorsByUUID.elements
+ while (elements.hasMoreElements) {
+ val actorRef = elements.nextElement
+ val proxy = typedActorFor(actorRef)
+ if (proxy.isDefined) {
+ TypedActorModule.typedActorObjectInstance.get.stop(proxy.get)
+ } else {
+ actorRef.stop
+ }
+ }
+ } else {
+ foreach(_.stop)
+ }
actorsByUUID.clear
actorsById.clear
log.info("All actors have been shut down and unregistered from ActorRegistry")
diff --git a/akka-actor/src/main/scala/util/ReflectiveAccess.scala b/akka-actor/src/main/scala/util/ReflectiveAccess.scala
index 6a719d3834..617f4c37ee 100644
--- a/akka-actor/src/main/scala/util/ReflectiveAccess.scala
+++ b/akka-actor/src/main/scala/util/ReflectiveAccess.scala
@@ -154,6 +154,9 @@ object ReflectiveAccess extends Logging {
type TypedActorObject = {
def isJoinPoint(message: Any): Boolean
def isJoinPointAndOneWay(message: Any): Boolean
+ def actorFor(proxy: AnyRef): Option[ActorRef]
+ def proxyFor(actorRef: ActorRef): Option[AnyRef]
+ def stop(anyRef: AnyRef) : Unit
}
lazy val isTypedActorEnabled = typedActorObjectInstance.isDefined
diff --git a/akka-typed-actor/src/main/scala/actor/TypedActor.scala b/akka-typed-actor/src/main/scala/actor/TypedActor.scala
index a4c7ddada1..3e2b924e0f 100644
--- a/akka-typed-actor/src/main/scala/actor/TypedActor.scala
+++ b/akka-typed-actor/src/main/scala/actor/TypedActor.scala
@@ -467,13 +467,24 @@ object TypedActor extends Logging {
def stop(proxy: AnyRef): Unit = AspectInitRegistry.unregister(proxy)
/**
- * Get the underlying dispatcher actor for the given Typed Actor.
+ * Get the underlying typed actor for the given Typed Actor.
*/
def actorFor(proxy: AnyRef): Option[ActorRef] =
ActorRegistry
.actorsFor(classOf[TypedActor])
.find(a => a.actor.asInstanceOf[TypedActor].proxy == proxy)
+ /**
+ * Get the typed actor proxy for the given Typed Actor.
+ */
+ def proxyFor(actorRef: ActorRef): Option[AnyRef] = {
+ if (actorRef.actor.isInstanceOf[TypedActor]) {
+ Some(actorRef.actor.asInstanceOf[TypedActor].proxy)
+ } else {
+ None
+ }
+ }
+
/**
* Links an other Typed Actor to this Typed Actor.
* @param supervisor the supervisor Typed Actor
diff --git a/akka-typed-actor/src/test/scala/actor/typed-actor/TypedActorSpec.scala b/akka-typed-actor/src/test/scala/actor/typed-actor/TypedActorSpec.scala
index 7de0a8f5df..8e05deff69 100644
--- a/akka-typed-actor/src/test/scala/actor/typed-actor/TypedActorSpec.scala
+++ b/akka-typed-actor/src/test/scala/actor/typed-actor/TypedActorSpec.scala
@@ -7,25 +7,139 @@ package se.scalablesolutions.akka.actor
import org.scalatest.Spec
import org.scalatest.Assertions
import org.scalatest.matchers.ShouldMatchers
-import org.scalatest.BeforeAndAfterAll
+import org.scalatest.BeforeAndAfterEach
import org.scalatest.junit.JUnitRunner
import org.junit.runner.RunWith
-import se.scalablesolutions.akka.dispatch.DefaultCompletableFuture;
+import se.scalablesolutions.akka.dispatch.DefaultCompletableFuture
+import TypedActorSpec._
+
+
+object TypedActorSpec {
+ trait MyTypedActor {
+ def sendOneWay(msg: String) : Unit
+ }
+
+ class MyTypedActorImpl extends TypedActor with MyTypedActor {
+ self.id = "my-custom-id"
+ def sendOneWay(msg: String) {
+ println("got " + msg)
+ }
+ }
+
+ class MyActor extends Actor {
+ self.id = "my-custom-id"
+ def receive = {
+ case msg: String => println("got " + msg)
+ }
+ }
+
+}
@RunWith(classOf[JUnitRunner])
class TypedActorSpec extends
Spec with
ShouldMatchers with
- BeforeAndAfterAll {
+ BeforeAndAfterEach {
+
+ var simplePojo: SimpleJavaPojo = null
+ var pojo: MyTypedActor = null;
+
+ override def beforeEach() {
+ simplePojo = TypedActor.newInstance(classOf[SimpleJavaPojo], classOf[SimpleJavaPojoImpl])
+ pojo = TypedActor.newInstance(classOf[MyTypedActor], classOf[MyTypedActorImpl])
+ }
+
+ override def afterEach() {
+ ActorRegistry.shutdownAll
+ }
describe("TypedActor") {
it("should resolve Future return from method defined to return a Future") {
- val pojo = TypedActor.newInstance(classOf[SimpleJavaPojo], classOf[SimpleJavaPojoImpl])
- val future = pojo.square(10)
+ val future = simplePojo.square(10)
future.await
future.result.isDefined should equal (true)
future.result.get should equal (100)
}
}
+
+ describe("TypedActor object") {
+ it("should support finding the underlying actor for a given proxy and the proxy for a given actor") {
+ val typedActorRef = TypedActor.actorFor(simplePojo).get
+ val typedActor = typedActorRef.actor.asInstanceOf[TypedActor]
+ assert(typedActor.proxy === simplePojo)
+ assert(TypedActor.proxyFor(typedActorRef).get === simplePojo)
+ }
+ }
+
+ describe("ActorRegistry") {
+ it("should support finding a typed actor by uuid ") {
+ val typedActorRef = TypedActor.actorFor(simplePojo).get
+ val uuid = typedActorRef.uuid
+ println("### 1")
+ assert(ActorRegistry.typedActorFor(newUuid()) === None)
+ println("### 2")
+ assert(ActorRegistry.typedActorFor(uuid).isDefined)
+ println("### 3")
+ assert(ActorRegistry.typedActorFor(uuid).get === simplePojo)
+ }
+
+ it("should support finding typed actors by id ") {
+ val typedActors = ActorRegistry.typedActorsFor("my-custom-id")
+ assert(typedActors.length === 1)
+ assert(typedActors.contains(pojo))
+
+ // creating untyped actor with same custom id
+ val actorRef = Actor.actorOf[MyActor].start
+ val typedActors2 = ActorRegistry.typedActorsFor("my-custom-id")
+ assert(typedActors2.length === 1)
+ assert(typedActors2.contains(pojo))
+ actorRef.stop
+ }
+
+ it("should support to filter typed actors") {
+ val actors = ActorRegistry.filterTypedActors(ta => ta.isInstanceOf[MyTypedActor])
+ assert(actors.length === 1)
+ assert(actors.contains(pojo))
+ }
+
+ it("should support to find typed actors by class") {
+ val actors = ActorRegistry.typedActorsFor(classOf[MyTypedActorImpl])
+ assert(actors.length === 1)
+ assert(actors.contains(pojo))
+ assert(ActorRegistry.typedActorsFor(classOf[MyActor]).isEmpty)
+ }
+
+ it("should support to get all typed actors") {
+ val actors = ActorRegistry.typedActors
+ assert(actors.length === 2)
+ assert(actors.contains(pojo))
+ assert(actors.contains(simplePojo))
+ }
+
+ it("should support to find typed actors by manifest") {
+ val actors = ActorRegistry.typedActorsFor[MyTypedActorImpl]
+ assert(actors.length === 1)
+ assert(actors.contains(pojo))
+ assert(ActorRegistry.typedActorsFor[MyActor].isEmpty)
+ }
+
+ it("should support foreach for typed actors") {
+ val actorRef = Actor.actorOf[MyActor].start
+ assert(ActorRegistry.actors.size === 3)
+ assert(ActorRegistry.typedActors.size === 2)
+ ActorRegistry.foreachTypedActor(TypedActor.stop(_))
+ assert(ActorRegistry.actors.size === 1)
+ assert(ActorRegistry.typedActors.size === 0)
+ }
+
+ it("should shutdown all typed and untyped actors") {
+ val actorRef = Actor.actorOf[MyActor].start
+ assert(ActorRegistry.actors.size === 3)
+ assert(ActorRegistry.typedActors.size === 2)
+ ActorRegistry.shutdownAll()
+ assert(ActorRegistry.actors.size === 0)
+ assert(ActorRegistry.typedActors.size === 0)
+ }
+ }
}
From ebf3dd0b52d11bdb5fc70d04043030b2affd2899 Mon Sep 17 00:00:00 2001
From: Viktor Klang
Date: Tue, 28 Sep 2010 11:21:05 +0200
Subject: [PATCH 27/82] Replacing use of == null and != null for Scala
---
akka-actor/src/main/scala/actor/ActorRef.scala | 3 +--
akka-actor/src/main/scala/config/Config.scala | 4 ++--
.../main/scala/dispatch/MessageHandling.scala | 1 -
.../src/main/scala/stm/Transaction.scala | 1 -
akka-actor/src/main/scala/util/Helpers.scala | 4 ++--
.../scala/component/TypedActorComponent.scala | 2 +-
akka-http/src/main/scala/Security.scala | 2 +-
.../src/main/scala/TransactionProtocol.scala | 2 +-
.../main/scala/VoldemortStorageBackend.scala | 2 +-
.../src/main/scala/remote/RemoteServer.scala | 1 -
.../serialization/SerializationProtocol.scala | 2 +-
.../ServerInitiatedRemoteActorSpec.scala | 8 ++++----
.../src/main/scala/ActorFactoryBean.scala | 12 ++++++------
akka-spring/src/main/scala/ActorParser.scala | 18 +++++++++---------
...ConfiggyPropertyPlaceholderConfigurer.scala | 2 +-
.../src/main/scala/DispatcherFactoryBean.scala | 4 ++--
akka-spring/src/main/scala/StringReflect.scala | 2 +-
.../SupervisionBeanDefinitionParser.scala | 4 ++--
.../main/scala/SupervisionFactoryBean.scala | 6 +++---
.../DispatcherBeanDefinitionParserTest.scala | 8 ++++----
.../scala/DispatcherSpringFeatureTest.scala | 10 +++++-----
.../SupervisionBeanDefinitionParserTest.scala | 6 +++---
.../scala/SupervisorSpringFeatureTest.scala | 8 ++++----
.../TypedActorBeanDefinitionParserTest.scala | 8 ++++----
.../src/main/scala/actor/TypedActor.scala | 2 +-
25 files changed, 59 insertions(+), 63 deletions(-)
diff --git a/akka-actor/src/main/scala/actor/ActorRef.scala b/akka-actor/src/main/scala/actor/ActorRef.scala
index 628c9fb7bb..ed54c761b0 100644
--- a/akka-actor/src/main/scala/actor/ActorRef.scala
+++ b/akka-actor/src/main/scala/actor/ActorRef.scala
@@ -630,7 +630,6 @@ trait ActorRef extends
override def hashCode: Int = HashCode.hash(HashCode.SEED, uuid)
override def equals(that: Any): Boolean = {
- that != null &&
that.isInstanceOf[ActorRef] &&
that.asInstanceOf[ActorRef].uuid == uuid
}
@@ -1302,7 +1301,7 @@ class LocalActorRef private[akka](
} catch {
case e: NoSuchFieldException =>
val parent = clazz.getSuperclass
- if (parent != null) findActorSelfField(parent)
+ if (parent ne null) findActorSelfField(parent)
else throw new IllegalActorStateException(
toString + " is not an Actor since it have not mixed in the 'Actor' trait")
}
diff --git a/akka-actor/src/main/scala/config/Config.scala b/akka-actor/src/main/scala/config/Config.scala
index c9d9a4968b..7a4ac4be48 100644
--- a/akka-actor/src/main/scala/config/Config.scala
+++ b/akka-actor/src/main/scala/config/Config.scala
@@ -33,7 +33,7 @@ object Config {
val HOME = {
val systemHome = System.getenv("AKKA_HOME")
- if (systemHome == null || systemHome.length == 0 || systemHome == ".") {
+ if ((systemHome eq null) || systemHome.length == 0 || systemHome == ".") {
val optionHome = System.getProperty("akka.home", "")
if (optionHome.length != 0) Some(optionHome)
else None
@@ -52,7 +52,7 @@ object Config {
"\n\tdue to: " + e.toString)
}
Configgy.config
- } else if (getClass.getClassLoader.getResource("akka.conf") != null) {
+ } else if (getClass.getClassLoader.getResource("akka.conf") ne null) {
try {
Configgy.configureFromResource("akka.conf", getClass.getClassLoader)
ConfigLogger.log.info("Config loaded from the application classpath.")
diff --git a/akka-actor/src/main/scala/dispatch/MessageHandling.scala b/akka-actor/src/main/scala/dispatch/MessageHandling.scala
index 06516e52d4..c9df3f3b87 100644
--- a/akka-actor/src/main/scala/dispatch/MessageHandling.scala
+++ b/akka-actor/src/main/scala/dispatch/MessageHandling.scala
@@ -39,7 +39,6 @@ final class MessageInvocation(val receiver: ActorRef,
}
override def equals(that: Any): Boolean = {
- that != null &&
that.isInstanceOf[MessageInvocation] &&
that.asInstanceOf[MessageInvocation].receiver.actor == receiver.actor &&
that.asInstanceOf[MessageInvocation].message == message
diff --git a/akka-actor/src/main/scala/stm/Transaction.scala b/akka-actor/src/main/scala/stm/Transaction.scala
index 60e0cd6772..9ea32d7ca6 100644
--- a/akka-actor/src/main/scala/stm/Transaction.scala
+++ b/akka-actor/src/main/scala/stm/Transaction.scala
@@ -165,7 +165,6 @@ object Transaction {
}
*/
override def equals(that: Any): Boolean = synchronized {
- that != null &&
that.isInstanceOf[Transaction] &&
that.asInstanceOf[Transaction].id == this.id
}
diff --git a/akka-actor/src/main/scala/util/Helpers.scala b/akka-actor/src/main/scala/util/Helpers.scala
index eab9e1981d..394b39e101 100644
--- a/akka-actor/src/main/scala/util/Helpers.scala
+++ b/akka-actor/src/main/scala/util/Helpers.scala
@@ -11,7 +11,7 @@ import java.security.MessageDigest
*/
object Helpers extends Logging {
- implicit def null2Option[T](t: T): Option[T] = if (t != null) Some(t) else None
+ implicit def null2Option[T](t: T): Option[T] = Option(t)
def intToBytes(value: Int): Array[Byte] = {
val bytes = new Array[Byte](4)
@@ -41,7 +41,7 @@ object Helpers extends Logging {
* if the actual type is not assignable from the given one.
*/
def narrow[T](o: Option[Any]): Option[T] = {
- require(o != null, "Option to be narrowed must not be null!")
+ require((o ne null), "Option to be narrowed must not be null!")
o.asInstanceOf[Option[T]]
}
diff --git a/akka-camel/src/main/scala/component/TypedActorComponent.scala b/akka-camel/src/main/scala/component/TypedActorComponent.scala
index 542705d0c6..f172cc808b 100644
--- a/akka-camel/src/main/scala/component/TypedActorComponent.scala
+++ b/akka-camel/src/main/scala/component/TypedActorComponent.scala
@@ -104,7 +104,7 @@ class TypedActorInfo(context: CamelContext, clazz: Class[_], strategy: Parameter
}
}
val superclass = clazz.getSuperclass
- if (superclass != null && !superclass.equals(classOf[AnyRef])) {
+ if ((superclass ne null) && !superclass.equals(classOf[AnyRef])) {
introspect(superclass)
}
}
diff --git a/akka-http/src/main/scala/Security.scala b/akka-http/src/main/scala/Security.scala
index b0f3c10be0..2db1e4981b 100644
--- a/akka-http/src/main/scala/Security.scala
+++ b/akka-http/src/main/scala/Security.scala
@@ -207,7 +207,7 @@ trait AuthenticationActor[C <: Credentials] extends Actor {
//Turns the aforementioned header value into an option
def authOption(r: Req): Option[String] = {
val a = auth(r)
- if (a != null && a.length > 0) Some(a) else None
+ if ((a ne null) && a.length > 0) Some(a) else None
}
}
diff --git a/akka-jta/src/main/scala/TransactionProtocol.scala b/akka-jta/src/main/scala/TransactionProtocol.scala
index f85b7ee1e3..487dece483 100644
--- a/akka-jta/src/main/scala/TransactionProtocol.scala
+++ b/akka-jta/src/main/scala/TransactionProtocol.scala
@@ -221,7 +221,7 @@ trait TransactionProtocol extends Logging {
private def storeInThreadLocal(tx: Transaction) = suspendedTx.set(tx)
private def fetchFromThreadLocal: Option[Transaction] = {
- if (suspendedTx != null && suspendedTx.get() != null) Some(suspendedTx.get.asInstanceOf[Transaction])
+ if ((suspendedTx ne null) && (suspendedTx.get() ne null)) Some(suspendedTx.get.asInstanceOf[Transaction])
else None
}
}
diff --git a/akka-persistence/akka-persistence-voldemort/src/main/scala/VoldemortStorageBackend.scala b/akka-persistence/akka-persistence-voldemort/src/main/scala/VoldemortStorageBackend.scala
index 9883eb121f..20b9804ed4 100644
--- a/akka-persistence/akka-persistence-voldemort/src/main/scala/VoldemortStorageBackend.scala
+++ b/akka-persistence/akka-persistence-voldemort/src/main/scala/VoldemortStorageBackend.scala
@@ -344,7 +344,7 @@ MapStorageBackend[Array[Byte], Array[Byte]] with
}
def initStoreClients() = {
- if (storeClientFactory != null) {
+ if (storeClientFactory ne null) {
storeClientFactory.close
}
diff --git a/akka-remote/src/main/scala/remote/RemoteServer.scala b/akka-remote/src/main/scala/remote/RemoteServer.scala
index bed9e9f933..74224d13a6 100644
--- a/akka-remote/src/main/scala/remote/RemoteServer.scala
+++ b/akka-remote/src/main/scala/remote/RemoteServer.scala
@@ -115,7 +115,6 @@ object RemoteServer {
result
}
override def equals(that: Any): Boolean = {
- that != null &&
that.isInstanceOf[Address] &&
that.asInstanceOf[Address].hostname == hostname &&
that.asInstanceOf[Address].port == port
diff --git a/akka-remote/src/main/scala/serialization/SerializationProtocol.scala b/akka-remote/src/main/scala/serialization/SerializationProtocol.scala
index c07417c0e2..9e047acdc3 100644
--- a/akka-remote/src/main/scala/serialization/SerializationProtocol.scala
+++ b/akka-remote/src/main/scala/serialization/SerializationProtocol.scala
@@ -337,7 +337,7 @@ object TypedActorSerialization {
proxy: AnyRef, format: Format[T]): SerializedTypedActorRefProtocol = {
val init = AspectInitRegistry.initFor(proxy)
- if (init == null) throw new IllegalArgumentException("Proxy for typed actor could not be found in AspectInitRegistry.")
+ if (init eq null) throw new IllegalArgumentException("Proxy for typed actor could not be found in AspectInitRegistry.")
SerializedTypedActorRefProtocol.newBuilder
.setActorRef(ActorSerialization.toSerializedActorRefProtocol(init.actorRef, format))
diff --git a/akka-remote/src/test/scala/remote/ServerInitiatedRemoteActorSpec.scala b/akka-remote/src/test/scala/remote/ServerInitiatedRemoteActorSpec.scala
index 8b61b30600..e961b500f2 100644
--- a/akka-remote/src/test/scala/remote/ServerInitiatedRemoteActorSpec.scala
+++ b/akka-remote/src/test/scala/remote/ServerInitiatedRemoteActorSpec.scala
@@ -201,18 +201,18 @@ class ServerInitiatedRemoteActorSpec extends JUnitSuite {
def shouldRegisterAndUnregister {
val actor1 = actorOf[RemoteActorSpecActorUnidirectional]
server.register("my-service-1", actor1)
- assert(server.actors().get("my-service-1") != null, "actor registered")
+ assert(server.actors().get("my-service-1") ne null, "actor registered")
server.unregister("my-service-1")
- assert(server.actors().get("my-service-1") == null, "actor unregistered")
+ assert(server.actors().get("my-service-1") eq null, "actor unregistered")
}
@Test
def shouldRegisterAndUnregisterByUuid {
val actor1 = actorOf[RemoteActorSpecActorUnidirectional]
server.register("uuid:" + actor1.uuid, actor1)
- assert(server.actorsByUuid().get(actor1.uuid.toString) != null, "actor registered")
+ assert(server.actorsByUuid().get(actor1.uuid.toString) ne null, "actor registered")
server.unregister("uuid:" + actor1.uuid)
- assert(server.actorsByUuid().get(actor1.uuid) == null, "actor unregistered")
+ assert(server.actorsByUuid().get(actor1.uuid) eq null, "actor unregistered")
}
}
diff --git a/akka-spring/src/main/scala/ActorFactoryBean.scala b/akka-spring/src/main/scala/ActorFactoryBean.scala
index fb35965418..87233ab451 100644
--- a/akka-spring/src/main/scala/ActorFactoryBean.scala
+++ b/akka-spring/src/main/scala/ActorFactoryBean.scala
@@ -100,9 +100,9 @@ class ActorFactoryBean extends AbstractFactoryBean[AnyRef] with Logging with App
}
private[akka] def createTypedInstance() : AnyRef = {
- if (interface == null || interface == "") throw new AkkaBeansException(
+ if ((interface eq null) || interface == "") throw new AkkaBeansException(
"The 'interface' part of the 'akka:actor' element in the Spring config file can't be null or empty string")
- if (implementation == null || implementation == "") throw new AkkaBeansException(
+ if ((implementation eq null) || implementation == "") throw new AkkaBeansException(
"The 'implementation' part of the 'akka:typed-actor' element in the Spring config file can't be null or empty string")
val typedActor: AnyRef = TypedActor.newInstance(interface.toClass, implementation.toClass, createConfig)
@@ -121,7 +121,7 @@ class ActorFactoryBean extends AbstractFactoryBean[AnyRef] with Logging with App
* Create an UntypedActor.
*/
private[akka] def createUntypedInstance() : ActorRef = {
- if (implementation == null || implementation == "") throw new AkkaBeansException(
+ if ((implementation eq null) || implementation == "") throw new AkkaBeansException(
"The 'implementation' part of the 'akka:untyped-actor' element in the Spring config file can't be null or empty string")
val actorRef = Actor.actorOf(implementation.toClass)
if (timeout > 0) {
@@ -199,11 +199,11 @@ class ActorFactoryBean extends AbstractFactoryBean[AnyRef] with Logging with App
config
}
- private[akka] def isRemote = (host != null) && (!host.isEmpty)
+ private[akka] def isRemote = (host ne null) && (!host.isEmpty)
private[akka] def hasDispatcher =
- (dispatcher != null) &&
- (dispatcher.dispatcherType != null) &&
+ (dispatcher ne null) &&
+ (dispatcher.dispatcherType ne null) &&
(!dispatcher.dispatcherType.isEmpty)
/**
diff --git a/akka-spring/src/main/scala/ActorParser.scala b/akka-spring/src/main/scala/ActorParser.scala
index 0947c6f944..e8048d1cd2 100644
--- a/akka-spring/src/main/scala/ActorParser.scala
+++ b/akka-spring/src/main/scala/ActorParser.scala
@@ -28,18 +28,18 @@ trait ActorParser extends BeanParser with DispatcherParser {
val dispatcherElement = DomUtils.getChildElementByTagName(element, DISPATCHER_TAG)
val propertyEntries = DomUtils.getChildElementsByTagName(element, PROPERTYENTRY_TAG)
- if (remoteElement != null) {
+ if (remoteElement ne null) {
objectProperties.host = mandatory(remoteElement, HOST)
objectProperties.port = mandatory(remoteElement, PORT)
- objectProperties.serverManaged = (remoteElement.getAttribute(MANAGED_BY) != null) && (remoteElement.getAttribute(MANAGED_BY).equals(SERVER_MANAGED))
+ objectProperties.serverManaged = (remoteElement.getAttribute(MANAGED_BY) ne null) && (remoteElement.getAttribute(MANAGED_BY).equals(SERVER_MANAGED))
val serviceName = remoteElement.getAttribute(SERVICE_NAME)
- if ((serviceName != null) && (!serviceName.isEmpty)) {
+ if ((serviceName ne null) && (!serviceName.isEmpty)) {
objectProperties.serviceName = serviceName
objectProperties.serverManaged = true
}
}
- if (dispatcherElement != null) {
+ if (dispatcherElement ne null) {
val dispatcherProperties = parseDispatcher(dispatcherElement)
objectProperties.dispatcher = dispatcherProperties
}
@@ -108,7 +108,7 @@ trait BeanParser extends Logging {
* @param attribute name of the mandatory attribute
*/
def mandatory(element: Element, attribute: String): String = {
- if ((element.getAttribute(attribute) == null) || (element.getAttribute(attribute).isEmpty)) {
+ if ((element.getAttribute(attribute) eq null) || (element.getAttribute(attribute).isEmpty)) {
throw new IllegalArgumentException("Mandatory attribute missing: " + attribute)
} else {
element.getAttribute(attribute)
@@ -122,7 +122,7 @@ trait BeanParser extends Logging {
*/
def mandatoryElement(element: Element, childName: String): Element = {
val childElement = DomUtils.getChildElementByTagName(element, childName);
- if (childElement == null) {
+ if (childElement eq null) {
throw new IllegalArgumentException("Mandatory element missing: ''")
} else {
childElement
@@ -150,7 +150,7 @@ trait DispatcherParser extends BeanParser {
if (hasRef(element)) {
val ref = element.getAttribute(REF)
dispatcherElement = element.getOwnerDocument.getElementById(ref)
- if (dispatcherElement == null) {
+ if (dispatcherElement eq null) {
throw new IllegalArgumentException("Referenced dispatcher not found: '" + ref + "'")
}
}
@@ -173,7 +173,7 @@ trait DispatcherParser extends BeanParser {
}
val threadPoolElement = DomUtils.getChildElementByTagName(dispatcherElement, THREAD_POOL_TAG);
- if (threadPoolElement != null) {
+ if (threadPoolElement ne null) {
if (properties.dispatcherType == THREAD_BASED) {
throw new IllegalArgumentException("Element 'thread-pool' not allowed for this dispatcher type.")
}
@@ -220,7 +220,7 @@ trait DispatcherParser extends BeanParser {
def hasRef(element: Element): Boolean = {
val ref = element.getAttribute(REF)
- (ref != null) && !ref.isEmpty
+ (ref ne null) && !ref.isEmpty
}
}
diff --git a/akka-spring/src/main/scala/ConfiggyPropertyPlaceholderConfigurer.scala b/akka-spring/src/main/scala/ConfiggyPropertyPlaceholderConfigurer.scala
index 411c36d86d..1360b62d9c 100644
--- a/akka-spring/src/main/scala/ConfiggyPropertyPlaceholderConfigurer.scala
+++ b/akka-spring/src/main/scala/ConfiggyPropertyPlaceholderConfigurer.scala
@@ -18,7 +18,7 @@ class ConfiggyPropertyPlaceholderConfigurer extends PropertyPlaceholderConfigure
* @param configgyResource akka.conf
*/
override def setLocation(configgyResource: Resource) {
- if (configgyResource == null) throw new IllegalArgumentException("Property 'config' must be set")
+ if (configgyResource eq null) throw new IllegalArgumentException("Property 'config' must be set")
val properties = loadAkkaConfig(configgyResource)
setProperties(properties)
}
diff --git a/akka-spring/src/main/scala/DispatcherFactoryBean.scala b/akka-spring/src/main/scala/DispatcherFactoryBean.scala
index 4d13fa6814..34a3a012ea 100644
--- a/akka-spring/src/main/scala/DispatcherFactoryBean.scala
+++ b/akka-spring/src/main/scala/DispatcherFactoryBean.scala
@@ -35,7 +35,7 @@ object DispatcherFactoryBean {
case _ => throw new IllegalArgumentException("unknown dispatcher type")
}
// build threadpool
- if ((properties.threadPool != null) && (properties.threadPool.queue != null)) {
+ if ((properties.threadPool ne null) && (properties.threadPool.queue ne null)) {
var threadPoolBuilder = dispatcher.asInstanceOf[ThreadPoolBuilder]
threadPoolBuilder = properties.threadPool.queue match {
case VAL_BOUNDED_ARRAY_BLOCKING_QUEUE => threadPoolBuilder.withNewThreadPoolWithArrayBlockingQueueWithCapacityAndFairness(properties.threadPool.capacity, properties.threadPool.fairness)
@@ -59,7 +59,7 @@ object DispatcherFactoryBean {
if (properties.threadPool.mailboxCapacity > -1) {
threadPoolBuilder.setMailboxCapacity(properties.threadPool.mailboxCapacity)
}
- if ((properties.threadPool.rejectionPolicy != null) && (!properties.threadPool.rejectionPolicy.isEmpty)) {
+ if ((properties.threadPool.rejectionPolicy ne null) && (!properties.threadPool.rejectionPolicy.isEmpty)) {
val policy: RejectedExecutionHandler = properties.threadPool.rejectionPolicy match {
case "abort-policy" => new AbortPolicy()
case "caller-runs-policy" => new CallerRunsPolicy()
diff --git a/akka-spring/src/main/scala/StringReflect.scala b/akka-spring/src/main/scala/StringReflect.scala
index 9e8cab8172..c0c8aab9ff 100644
--- a/akka-spring/src/main/scala/StringReflect.scala
+++ b/akka-spring/src/main/scala/StringReflect.scala
@@ -17,7 +17,7 @@ object StringReflect {
* @author michaelkober
*/
class StringReflect(val self: String) {
- if (self == null || self == "") throw new IllegalArgumentException("Class name can't be null or empty string [" + self + "]")
+ if ((self eq null) || self == "") throw new IllegalArgumentException("Class name can't be null or empty string [" + self + "]")
def toClass[T <: AnyRef]: Class[T] = {
val clazz = Class.forName(self)
clazz.asInstanceOf[Class[T]]
diff --git a/akka-spring/src/main/scala/SupervisionBeanDefinitionParser.scala b/akka-spring/src/main/scala/SupervisionBeanDefinitionParser.scala
index cc88e39f91..164018f588 100644
--- a/akka-spring/src/main/scala/SupervisionBeanDefinitionParser.scala
+++ b/akka-spring/src/main/scala/SupervisionBeanDefinitionParser.scala
@@ -33,11 +33,11 @@ class SupervisionBeanDefinitionParser extends AbstractSingleBeanDefinitionParser
val strategyElement = mandatoryElement(element, STRATEGY_TAG)
val typedActorsElement = DomUtils.getChildElementByTagName(element, TYPED_ACTORS_TAG)
val untypedActorsElement = DomUtils.getChildElementByTagName(element, UNTYPED_ACTORS_TAG)
- if ((typedActorsElement == null) && (untypedActorsElement == null)) {
+ if ((typedActorsElement eq null) && (untypedActorsElement eq null)) {
throw new IllegalArgumentException("One of 'akka:typed-actors' or 'akka:untyped-actors' needed.")
}
parseRestartStrategy(strategyElement, builder)
- if (typedActorsElement != null) {
+ if (typedActorsElement ne null) {
builder.addPropertyValue("typed", AkkaSpringConfigurationTags.TYPED_ACTOR_TAG)
parseTypedActorList(typedActorsElement, builder)
} else {
diff --git a/akka-spring/src/main/scala/SupervisionFactoryBean.scala b/akka-spring/src/main/scala/SupervisionFactoryBean.scala
index a19b6fdeea..657a40c90a 100644
--- a/akka-spring/src/main/scala/SupervisionFactoryBean.scala
+++ b/akka-spring/src/main/scala/SupervisionFactoryBean.scala
@@ -57,8 +57,8 @@ class SupervisionFactoryBean extends AbstractFactoryBean[AnyRef] {
private[akka] def createComponent(props: ActorProperties): Component = {
import StringReflect._
val lifeCycle = if (!props.lifecycle.isEmpty && props.lifecycle.equalsIgnoreCase(VAL_LIFECYCYLE_TEMPORARY)) new LifeCycle(new Temporary()) else new LifeCycle(new Permanent())
- val isRemote = (props.host != null) && (!props.host.isEmpty)
- val withInterface = (props.interface != null) && (!props.interface.isEmpty)
+ val isRemote = (props.host ne null) && (!props.host.isEmpty)
+ val withInterface = (props.interface ne null) && (!props.interface.isEmpty)
if (isRemote) {
//val remote = new RemoteAddress(props.host, props.port)
val remote = new RemoteAddress(props.host, props.port.toInt)
@@ -82,7 +82,7 @@ class SupervisionFactoryBean extends AbstractFactoryBean[AnyRef] {
private[akka] def createSupervise(props: ActorProperties): Server = {
import StringReflect._
val lifeCycle = if (!props.lifecycle.isEmpty && props.lifecycle.equalsIgnoreCase(VAL_LIFECYCYLE_TEMPORARY)) new LifeCycle(new Temporary()) else new LifeCycle(new Permanent())
- val isRemote = (props.host != null) && (!props.host.isEmpty)
+ val isRemote = (props.host ne null) && (!props.host.isEmpty)
val actorRef = Actor.actorOf(props.target.toClass)
if (props.timeout > 0) {
actorRef.setTimeout(props.timeout)
diff --git a/akka-spring/src/test/scala/DispatcherBeanDefinitionParserTest.scala b/akka-spring/src/test/scala/DispatcherBeanDefinitionParserTest.scala
index 9dfb5bce94..85b233e034 100644
--- a/akka-spring/src/test/scala/DispatcherBeanDefinitionParserTest.scala
+++ b/akka-spring/src/test/scala/DispatcherBeanDefinitionParserTest.scala
@@ -24,7 +24,7 @@ class DispatcherBeanDefinitionParserTest extends Spec with ShouldMatchers {
type="executor-based-event-driven"
name="myDispatcher"/>
var props = parser.parseDispatcher(dom(xml).getDocumentElement);
- assert(props != null)
+ assert(props ne null)
assert(props.dispatcherType === "executor-based-event-driven")
assert(props.name === "myDispatcher")
@@ -45,7 +45,7 @@ class DispatcherBeanDefinitionParserTest extends Spec with ShouldMatchers {
keep-alive="2000"
rejection-policy="caller-runs-policy"/>
val props = parser.parseThreadPool(dom(xml).getDocumentElement);
- assert(props != null)
+ assert(props ne null)
assert(props.queue == "bounded-array-blocking-queue")
assert(props.capacity == 100)
assert(props.fairness)
@@ -66,7 +66,7 @@ class DispatcherBeanDefinitionParserTest extends Spec with ShouldMatchers {
keep-alive="1000"/>
val props = parser.parseDispatcher(dom(xml).getDocumentElement);
- assert(props != null)
+ assert(props ne null)
assert(props.dispatcherType == "executor-based-event-driven")
assert(props.name == "myDispatcher")
assert(props.threadPool.corePoolSize == 2)
@@ -97,7 +97,7 @@ class DispatcherBeanDefinitionParserTest extends Spec with ShouldMatchers {
type="hawt"
aggregate="false"/>
var props = parser.parseDispatcher(dom(xml).getDocumentElement);
- assert(props != null)
+ assert(props ne null)
assert(props.dispatcherType === "hawt")
assert(props.aggregate === false)
}
diff --git a/akka-spring/src/test/scala/DispatcherSpringFeatureTest.scala b/akka-spring/src/test/scala/DispatcherSpringFeatureTest.scala
index a388bb418e..7d886c7fb0 100644
--- a/akka-spring/src/test/scala/DispatcherSpringFeatureTest.scala
+++ b/akka-spring/src/test/scala/DispatcherSpringFeatureTest.scala
@@ -47,7 +47,7 @@ class DispatcherSpringFeatureTest extends FeatureSpec with ShouldMatchers {
scenario("get a dispatcher via ref from context") {
val context = new ClassPathXmlApplicationContext("/dispatcher-config.xml")
val pojo = context.getBean("typed-actor-with-dispatcher-ref").asInstanceOf[IMyPojo]
- assert(pojo != null)
+ assert(pojo ne null)
}
scenario("get a executor-event-driven-dispatcher with blocking-queue with unbounded capacity from context") {
@@ -99,7 +99,7 @@ class DispatcherSpringFeatureTest extends FeatureSpec with ShouldMatchers {
scenario("get a executor-based-event-driven-work-stealing-dispatcher from context") {
val context = new ClassPathXmlApplicationContext("/dispatcher-config.xml")
val dispatcher = context.getBean("executor-based-event-driven-work-stealing-dispatcher").asInstanceOf[ExecutorBasedEventDrivenWorkStealingDispatcher]
- assert(dispatcher != null)
+ assert(dispatcher ne null)
assert(dispatcher.name === "akka:event-driven-work-stealing:dispatcher:workStealingDispatcher")
val executor = getThreadPoolExecutorAndAssert(dispatcher)
assert(executor.getQueue().isInstanceOf[BlockingQueue[Runnable]])
@@ -108,7 +108,7 @@ class DispatcherSpringFeatureTest extends FeatureSpec with ShouldMatchers {
scenario("get a hawt-dispatcher from context") {
val context = new ClassPathXmlApplicationContext("/dispatcher-config.xml")
val dispatcher = context.getBean("hawt-dispatcher").asInstanceOf[HawtDispatcher]
- assert(dispatcher != null)
+ assert(dispatcher ne null)
assert(dispatcher.toString === "HawtDispatchEventDrivenDispatcher")
assert(dispatcher.aggregate === false)
}
@@ -116,7 +116,7 @@ class DispatcherSpringFeatureTest extends FeatureSpec with ShouldMatchers {
scenario("get a thread-based-dispatcher for typed actor from context") {
val context = new ClassPathXmlApplicationContext("/dispatcher-config.xml")
val pojo = context.getBean("typed-actor-with-thread-based-dispatcher").asInstanceOf[IMyPojo]
- assert(pojo != null)
+ assert(pojo ne null)
}
scenario("get a thread-based-dispatcher for untyped from context") {
@@ -138,7 +138,7 @@ class DispatcherSpringFeatureTest extends FeatureSpec with ShouldMatchers {
val field = pool.getClass.getDeclaredField("se$scalablesolutions$akka$dispatch$ThreadPoolBuilder$$threadPoolBuilder")
field.setAccessible(true)
val executor = field.get(pool).asInstanceOf[ThreadPoolExecutor]
- assert(executor != null)
+ assert(executor ne null)
executor;
}
diff --git a/akka-spring/src/test/scala/SupervisionBeanDefinitionParserTest.scala b/akka-spring/src/test/scala/SupervisionBeanDefinitionParserTest.scala
index fd9ad3e3bd..15734fc9fa 100644
--- a/akka-spring/src/test/scala/SupervisionBeanDefinitionParserTest.scala
+++ b/akka-spring/src/test/scala/SupervisionBeanDefinitionParserTest.scala
@@ -28,7 +28,7 @@ class SupervisionBeanDefinitionParserTest extends Spec with ShouldMatchers {
it("should be able to parse typed actor configuration") {
val props = parser.parseActor(createTypedActorElement);
- assert(props != null)
+ assert(props ne null)
assert(props.timeout == 1000)
assert(props.target == "foo.bar.MyPojo")
assert(props.transactional)
@@ -37,7 +37,7 @@ class SupervisionBeanDefinitionParserTest extends Spec with ShouldMatchers {
it("should parse the supervisor restart strategy") {
parser.parseSupervisor(createSupervisorElement, builder);
val strategy = builder.getBeanDefinition.getPropertyValues.getPropertyValue("restartStrategy").getValue.asInstanceOf[RestartStrategy]
- assert(strategy != null)
+ assert(strategy ne null)
assert(strategy.scheme match {
case x:AllForOne => true
case _ => false })
@@ -48,7 +48,7 @@ class SupervisionBeanDefinitionParserTest extends Spec with ShouldMatchers {
it("should parse the supervised typed actors") {
parser.parseSupervisor(createSupervisorElement, builder);
val supervised = builder.getBeanDefinition.getPropertyValues.getPropertyValue("supervised").getValue.asInstanceOf[List[ActorProperties]]
- assert(supervised != null)
+ assert(supervised ne null)
expect(4) { supervised.length }
val iterator = supervised.iterator
val prop1 = iterator.next
diff --git a/akka-spring/src/test/scala/SupervisorSpringFeatureTest.scala b/akka-spring/src/test/scala/SupervisorSpringFeatureTest.scala
index 1a35451315..89a779039c 100644
--- a/akka-spring/src/test/scala/SupervisorSpringFeatureTest.scala
+++ b/akka-spring/src/test/scala/SupervisorSpringFeatureTest.scala
@@ -34,11 +34,11 @@ class SupervisorSpringFeatureTest extends FeatureSpec with ShouldMatchers {
val myConfigurator = context.getBean("supervision1").asInstanceOf[TypedActorConfigurator]
// get TypedActors
val foo = myConfigurator.getInstance(classOf[IFoo])
- assert(foo != null)
+ assert(foo ne null)
val bar = myConfigurator.getInstance(classOf[IBar])
- assert(bar != null)
+ assert(bar ne null)
val pojo = myConfigurator.getInstance(classOf[IMyPojo])
- assert(pojo != null)
+ assert(pojo ne null)
}
scenario("get a supervisor for untyped actors from context") {
@@ -51,7 +51,7 @@ class SupervisorSpringFeatureTest extends FeatureSpec with ShouldMatchers {
val context = new ClassPathXmlApplicationContext("/supervisor-config.xml")
val myConfigurator = context.getBean("supervision-with-dispatcher").asInstanceOf[TypedActorConfigurator]
val foo = myConfigurator.getInstance(classOf[IFoo])
- assert(foo != null)
+ assert(foo ne null)
}
}
}
diff --git a/akka-spring/src/test/scala/TypedActorBeanDefinitionParserTest.scala b/akka-spring/src/test/scala/TypedActorBeanDefinitionParserTest.scala
index 52663afe63..15ed97bd27 100644
--- a/akka-spring/src/test/scala/TypedActorBeanDefinitionParserTest.scala
+++ b/akka-spring/src/test/scala/TypedActorBeanDefinitionParserTest.scala
@@ -31,7 +31,7 @@ class TypedActorBeanDefinitionParserTest extends Spec with ShouldMatchers {
val props = parser.parseActor(dom(xml).getDocumentElement);
- assert(props != null)
+ assert(props ne null)
assert(props.timeout === 1000)
assert(props.target === "foo.bar.MyPojo")
assert(props.transactional)
@@ -53,7 +53,7 @@ class TypedActorBeanDefinitionParserTest extends Spec with ShouldMatchers {
val props = parser.parseActor(dom(xml).getDocumentElement);
- assert(props != null)
+ assert(props ne null)
assert(props.dispatcher.dispatcherType === "thread-based")
}
@@ -63,7 +63,7 @@ class TypedActorBeanDefinitionParserTest extends Spec with ShouldMatchers {
val props = parser.parseActor(dom(xml).getDocumentElement);
- assert(props != null)
+ assert(props ne null)
assert(props.host === "com.some.host")
assert(props.port === "9999")
assert(!props.serverManaged)
@@ -75,7 +75,7 @@ class TypedActorBeanDefinitionParserTest extends Spec with ShouldMatchers {
val props = parser.parseActor(dom(xml).getDocumentElement);
- assert(props != null)
+ assert(props ne null)
assert(props.host === "com.some.host")
assert(props.port === "9999")
assert(props.serviceName === "my-service")
diff --git a/akka-typed-actor/src/main/scala/actor/TypedActor.scala b/akka-typed-actor/src/main/scala/actor/TypedActor.scala
index a4c7ddada1..7b35abfa57 100644
--- a/akka-typed-actor/src/main/scala/actor/TypedActor.scala
+++ b/akka-typed-actor/src/main/scala/actor/TypedActor.scala
@@ -543,7 +543,7 @@ object TypedActor extends Logging {
}
def isTransactional(clazz: Class[_]): Boolean = {
- if (clazz == null) false
+ if (clazz eq null) false
else if (clazz.isAssignableFrom(classOf[TypedTransactor])) true
else isTransactional(clazz.getSuperclass)
}
From e08ec0ea4c345c8e21299f6968390708626f665a Mon Sep 17 00:00:00 2001
From: Viktor Klang
Date: Tue, 28 Sep 2010 14:08:23 +0200
Subject: [PATCH 28/82] =?UTF-8?q?Removing=20classloader=20field=20(volatil?=
=?UTF-8?q?e)=20from=20LocalActorRef,=20wasn=C2=B4t=20used?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
akka-actor/src/main/scala/actor/ActorRef.scala | 3 ---
.../src/main/scala/serialization/SerializationProtocol.scala | 1 -
2 files changed, 4 deletions(-)
diff --git a/akka-actor/src/main/scala/actor/ActorRef.scala b/akka-actor/src/main/scala/actor/ActorRef.scala
index ed54c761b0..a61db83e4a 100644
--- a/akka-actor/src/main/scala/actor/ActorRef.scala
+++ b/akka-actor/src/main/scala/actor/ActorRef.scala
@@ -668,7 +668,6 @@ class LocalActorRef private[akka](
@volatile private var isInInitialization = false
@volatile private var runActorInitialization = false
@volatile private var isDeserialized = false
- @volatile private var loader: Option[ClassLoader] = None
@volatile private var maxNrOfRetriesCount: Int = 0
@volatile private var restartsWithinTimeRangeTimestamp: Long = 0L
@volatile private var _mailbox: AnyRef = _
@@ -695,10 +694,8 @@ class LocalActorRef private[akka](
__lifeCycle: Option[LifeCycle],
__supervisor: Option[ActorRef],
__hotswap: Option[PartialFunction[Any, Unit]],
- __loader: ClassLoader,
__factory: () => Actor) = {
this(__factory)
- loader = Some(__loader)
isDeserialized = true
_uuid = __uuid
id = __id
diff --git a/akka-remote/src/main/scala/serialization/SerializationProtocol.scala b/akka-remote/src/main/scala/serialization/SerializationProtocol.scala
index 9e047acdc3..5b881f5269 100644
--- a/akka-remote/src/main/scala/serialization/SerializationProtocol.scala
+++ b/akka-remote/src/main/scala/serialization/SerializationProtocol.scala
@@ -202,7 +202,6 @@ object ActorSerialization {
lifeCycle,
supervisor,
hotswap,
- classLoader, // TODO: should we fall back to getClass.getClassLoader?
factory)
val messages = protocol.getMessagesList.toArray.toList.asInstanceOf[List[RemoteRequestProtocol]]
From 4817af9daf9e7b40a4b6d0de2147597f2458bf61 Mon Sep 17 00:00:00 2001
From: Michael Kober
Date: Tue, 28 Sep 2010 13:33:07 +0200
Subject: [PATCH 29/82] closing ticket 444, moved RemoteActorSet to
ActorRegistry
---
.../src/main/scala/actor/ActorRegistry.scala | 36 ++++++++++++-
akka-actor/src/main/scala/util/Address.scala | 23 ++++++++
.../src/main/scala/remote/RemoteClient.scala | 10 ++--
.../src/main/scala/remote/RemoteServer.scala | 53 +++----------------
.../serialization/SerializationProtocol.scala | 2 +-
5 files changed, 71 insertions(+), 53 deletions(-)
create mode 100644 akka-actor/src/main/scala/util/Address.scala
diff --git a/akka-actor/src/main/scala/actor/ActorRegistry.scala b/akka-actor/src/main/scala/actor/ActorRegistry.scala
index e425451470..241cb9c8c4 100644
--- a/akka-actor/src/main/scala/actor/ActorRegistry.scala
+++ b/akka-actor/src/main/scala/actor/ActorRegistry.scala
@@ -4,14 +4,15 @@
package se.scalablesolutions.akka.actor
-import scala.collection.mutable.ListBuffer
+import scala.collection.mutable.{ListBuffer, Map}
import scala.reflect.Manifest
import java.util.concurrent.{ConcurrentSkipListSet, ConcurrentHashMap}
import java.util.{Set => JSet}
-import se.scalablesolutions.akka.util.ListenerManagement
import annotation.tailrec
+import se.scalablesolutions.akka.util.{ReadWriteGuard, Address, ListenerManagement}
+import java.net.InetSocketAddress
/**
* Base trait for ActorRegistry events, allows listen to when an actor is added and removed from the ActorRegistry.
@@ -37,6 +38,8 @@ case class ActorUnregistered(actor: ActorRef) extends ActorRegistryEvent
object ActorRegistry extends ListenerManagement {
private val actorsByUUID = new ConcurrentHashMap[Uuid, ActorRef]
private val actorsById = new Index[String,ActorRef]
+ private val remoteActorSets = Map[Address, RemoteActorSet]()
+ private val guard = new ReadWriteGuard
/**
* Returns all actors in the system.
@@ -150,6 +153,35 @@ object ActorRegistry extends ListenerManagement {
actorsById.clear
log.info("All actors have been shut down and unregistered from ActorRegistry")
}
+
+ /**
+ * Get the remote actors for the given server address. For internal use only.
+ */
+ private[akka] def actorsFor(remoteServerAddress: Address): RemoteActorSet = guard.withWriteGuard {
+ remoteActorSets.getOrElseUpdate(remoteServerAddress, new RemoteActorSet)
+ }
+
+ private[akka] def registerActorByUuid(address: InetSocketAddress, uuid: String, actor: ActorRef) {
+ actorsByUuid(Address(address.getHostName, address.getPort)).putIfAbsent(uuid, actor)
+ }
+
+ private[akka] def registerTypedActorByUuid(address: InetSocketAddress, uuid: String, typedActor: AnyRef) {
+ typedActorsByUuid(Address(address.getHostName, address.getPort)).putIfAbsent(uuid, typedActor)
+ }
+
+
+
+ private[akka] def actors(address: Address) = actorsFor(address).actors
+ private[akka] def actorsByUuid(address: Address) = actorsFor(address).actorsByUuid
+ private[akka] def typedActors(address: Address) = actorsFor(address).typedActors
+ private[akka] def typedActorsByUuid(address: Address) = actorsFor(address).typedActorsByUuid
+
+ private[akka] class RemoteActorSet {
+ private[ActorRegistry] val actors = new ConcurrentHashMap[String, ActorRef]
+ private[ActorRegistry] val actorsByUuid = new ConcurrentHashMap[String, ActorRef]
+ private[ActorRegistry] val typedActors = new ConcurrentHashMap[String, AnyRef]
+ private[ActorRegistry] val typedActorsByUuid = new ConcurrentHashMap[String, AnyRef]
+ }
}
class Index[K <: AnyRef,V <: AnyRef : Manifest] {
diff --git a/akka-actor/src/main/scala/util/Address.scala b/akka-actor/src/main/scala/util/Address.scala
new file mode 100644
index 0000000000..34c3f51bd4
--- /dev/null
+++ b/akka-actor/src/main/scala/util/Address.scala
@@ -0,0 +1,23 @@
+/**
+ * Copyright (C) 2009-2010 Scalable Solutions AB
+ */
+package se.scalablesolutions.akka.util
+
+object Address {
+ def apply(hostname: String, port: Int) = new Address(hostname, port)
+}
+
+class Address(val hostname: String, val port: Int) {
+ override def hashCode: Int = {
+ var result = HashCode.SEED
+ result = HashCode.hash(result, hostname)
+ result = HashCode.hash(result, port)
+ result
+ }
+
+ override def equals(that: Any): Boolean = {
+ that.isInstanceOf[Address] &&
+ that.asInstanceOf[Address].hostname == hostname &&
+ that.asInstanceOf[Address].port == port
+ }
+}
\ No newline at end of file
diff --git a/akka-remote/src/main/scala/remote/RemoteClient.scala b/akka-remote/src/main/scala/remote/RemoteClient.scala
index bb9714bc61..2694c9aee8 100644
--- a/akka-remote/src/main/scala/remote/RemoteClient.scala
+++ b/akka-remote/src/main/scala/remote/RemoteClient.scala
@@ -7,7 +7,6 @@ package se.scalablesolutions.akka.remote
import se.scalablesolutions.akka.remote.protocol.RemoteProtocol.{ActorType => ActorTypeProtocol, _}
import se.scalablesolutions.akka.actor.{Exit, Actor, ActorRef, ActorType, RemoteActorRef, IllegalActorStateException}
import se.scalablesolutions.akka.dispatch.{DefaultCompletableFuture, CompletableFuture}
-import se.scalablesolutions.akka.util.{ListenerManagement, Logging, Duration}
import se.scalablesolutions.akka.actor.{Uuid,newUuid,uuidFrom}
import se.scalablesolutions.akka.config.Config._
import se.scalablesolutions.akka.serialization.RemoteActorSerialization._
@@ -31,6 +30,7 @@ import java.util.concurrent.atomic.AtomicLong
import scala.collection.mutable.{HashSet, HashMap}
import scala.reflect.BeanProperty
import se.scalablesolutions.akka.actor._
+import se.scalablesolutions.akka.util.{Address, ListenerManagement, Logging, Duration}
/**
* Life-cycle events for RemoteClient.
@@ -63,7 +63,7 @@ object RemoteClient extends Logging {
val RECONNECT_DELAY = Duration(config.getInt("akka.remote.client.reconnect-delay", 5), TIME_UNIT)
private val remoteClients = new HashMap[String, RemoteClient]
- private val remoteActors = new HashMap[RemoteServer.Address, HashSet[Uuid]]
+ private val remoteActors = new HashMap[Address, HashSet[Uuid]]
def actorFor(classNameOrServiceId: String, hostname: String, port: Int): ActorRef =
actorFor(classNameOrServiceId, classNameOrServiceId, 5000L, hostname, port, None)
@@ -163,16 +163,16 @@ object RemoteClient extends Logging {
}
def register(hostname: String, port: Int, uuid: Uuid) = synchronized {
- actorsFor(RemoteServer.Address(hostname, port)) += uuid
+ actorsFor(Address(hostname, port)) += uuid
}
private[akka] def unregister(hostname: String, port: Int, uuid: Uuid) = synchronized {
- val set = actorsFor(RemoteServer.Address(hostname, port))
+ val set = actorsFor(Address(hostname, port))
set -= uuid
if (set.isEmpty) shutdownClientFor(new InetSocketAddress(hostname, port))
}
- private[akka] def actorsFor(remoteServerAddress: RemoteServer.Address): HashSet[Uuid] = {
+ private[akka] def actorsFor(remoteServerAddress: Address): HashSet[Uuid] = {
val set = remoteActors.get(remoteServerAddress)
if (set.isDefined && (set.get ne null)) set.get
else {
diff --git a/akka-remote/src/main/scala/remote/RemoteServer.scala b/akka-remote/src/main/scala/remote/RemoteServer.scala
index 74224d13a6..1c62f6f7fb 100644
--- a/akka-remote/src/main/scala/remote/RemoteServer.scala
+++ b/akka-remote/src/main/scala/remote/RemoteServer.scala
@@ -10,7 +10,7 @@ import java.util.concurrent.{ConcurrentHashMap, Executors}
import java.util.{Map => JMap}
import se.scalablesolutions.akka.actor.{
- Actor, TypedActor, ActorRef, IllegalActorStateException, RemoteActorSystemMessage,uuidFrom,Uuid}
+ Actor, TypedActor, ActorRef, IllegalActorStateException, RemoteActorSystemMessage,uuidFrom,Uuid, ActorRegistry}
import se.scalablesolutions.akka.actor.Actor._
import se.scalablesolutions.akka.util._
import se.scalablesolutions.akka.remote.protocol.RemoteProtocol._
@@ -103,43 +103,9 @@ object RemoteServer {
} else */false
}
- object Address {
- def apply(hostname: String, port: Int) = new Address(hostname, port)
- }
-
- class Address(val hostname: String, val port: Int) {
- override def hashCode: Int = {
- var result = HashCode.SEED
- result = HashCode.hash(result, hostname)
- result = HashCode.hash(result, port)
- result
- }
- override def equals(that: Any): Boolean = {
- that.isInstanceOf[Address] &&
- that.asInstanceOf[Address].hostname == hostname &&
- that.asInstanceOf[Address].port == port
- }
- }
-
- private class RemoteActorSet {
- private[RemoteServer] val actors = new ConcurrentHashMap[String, ActorRef]
- private[RemoteServer] val actorsByUuid = new ConcurrentHashMap[String, ActorRef]
- private[RemoteServer] val typedActors = new ConcurrentHashMap[String, AnyRef]
- private[RemoteServer] val typedActorsByUuid = new ConcurrentHashMap[String, AnyRef]
- }
-
private val guard = new ReadWriteGuard
- private val remoteActorSets = Map[Address, RemoteActorSet]()
private val remoteServers = Map[Address, RemoteServer]()
- private[akka] def registerActorByUuid(address: InetSocketAddress, uuid: String, actor: ActorRef) = guard.withWriteGuard {
- actorsFor(RemoteServer.Address(address.getHostName, address.getPort)).actorsByUuid.put(uuid, actor)
- }
-
- private[akka] def registerTypedActorByUuid(address: InetSocketAddress, uuid: String, typedActor: AnyRef) = guard.withWriteGuard {
- actorsFor(RemoteServer.Address(address.getHostName, address.getPort)).typedActors.put(uuid, typedActor)
- }
-
private[akka] def getOrCreateServer(address: InetSocketAddress): RemoteServer = guard.withWriteGuard {
serverFor(address) match {
case Some(server) => server
@@ -161,10 +127,7 @@ object RemoteServer {
private[akka] def unregister(hostname: String, port: Int) = guard.withWriteGuard {
remoteServers.remove(Address(hostname, port))
}
-
- private def actorsFor(remoteServerAddress: RemoteServer.Address): RemoteActorSet = {
- remoteActorSets.getOrElseUpdate(remoteServerAddress,new RemoteActorSet)
- }
+
}
/**
@@ -197,7 +160,7 @@ class RemoteServer extends Logging with ListenerManagement {
import RemoteServer._
def name = "RemoteServer@" + hostname + ":" + port
- private[akka] var address = RemoteServer.Address(RemoteServer.HOSTNAME,RemoteServer.PORT)
+ private[akka] var address = Address(RemoteServer.HOSTNAME,RemoteServer.PORT)
def hostname = address.hostname
def port = address.port
@@ -236,7 +199,7 @@ class RemoteServer extends Logging with ListenerManagement {
private def start(_hostname: String, _port: Int, loader: Option[ClassLoader]): RemoteServer = synchronized {
try {
if (!_isRunning) {
- address = RemoteServer.Address(_hostname,_port)
+ address = Address(_hostname,_port)
log.info("Starting remote server at [%s:%s]", hostname, port)
RemoteServer.register(hostname, port, this)
val pipelineFactory = new RemoteServerPipelineFactory(
@@ -379,10 +342,10 @@ class RemoteServer extends Logging with ListenerManagement {
protected[akka] override def notifyListeners(message: => Any): Unit = super.notifyListeners(message)
- private[akka] def actors() = RemoteServer.actorsFor(address).actors
- private[akka] def actorsByUuid() = RemoteServer.actorsFor(address).actorsByUuid
- private[akka] def typedActors() = RemoteServer.actorsFor(address).typedActors
- private[akka] def typedActorsByUuid() = RemoteServer.actorsFor(address).typedActorsByUuid
+ private[akka] def actors() = ActorRegistry.actors(address)
+ private[akka] def actorsByUuid() = ActorRegistry.actorsByUuid(address)
+ private[akka] def typedActors() = ActorRegistry.typedActors(address)
+ private[akka] def typedActorsByUuid() = ActorRegistry.typedActorsByUuid(address)
}
object RemoteServerSslContext {
diff --git a/akka-remote/src/main/scala/serialization/SerializationProtocol.scala b/akka-remote/src/main/scala/serialization/SerializationProtocol.scala
index 9e047acdc3..1383cbd261 100644
--- a/akka-remote/src/main/scala/serialization/SerializationProtocol.scala
+++ b/akka-remote/src/main/scala/serialization/SerializationProtocol.scala
@@ -251,7 +251,7 @@ object RemoteActorSerialization {
Actor.log.debug("Register serialized Actor [%s] as remote @ [%s:%s]", actorClass.getName, host, port)
RemoteServer.getOrCreateServer(homeAddress)
- RemoteServer.registerActorByUuid(homeAddress, uuid.toString, ar)
+ ActorRegistry.registerActorByUuid(homeAddress, uuid.toString, ar)
RemoteActorRefProtocol.newBuilder
.setClassOrServiceName(uuid.toString)
From 660b14e9757864668f1f16fa7f9568cb19a58b04 Mon Sep 17 00:00:00 2001
From: Viktor Klang
Date: Tue, 28 Sep 2010 15:25:25 +0200
Subject: [PATCH 30/82] =?UTF-8?q?Removing=20isDeserialize=20volatile=20fie?=
=?UTF-8?q?ld=20since=20it=20doesn=C2=B4t=20seem=20to=20have=20any=20use?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
akka-actor/src/main/scala/actor/ActorRef.scala | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/akka-actor/src/main/scala/actor/ActorRef.scala b/akka-actor/src/main/scala/actor/ActorRef.scala
index a61db83e4a..3fdc39d03e 100644
--- a/akka-actor/src/main/scala/actor/ActorRef.scala
+++ b/akka-actor/src/main/scala/actor/ActorRef.scala
@@ -667,7 +667,6 @@ class LocalActorRef private[akka](
@volatile private[akka] var _supervisor: Option[ActorRef] = None
@volatile private var isInInitialization = false
@volatile private var runActorInitialization = false
- @volatile private var isDeserialized = false
@volatile private var maxNrOfRetriesCount: Int = 0
@volatile private var restartsWithinTimeRangeTimestamp: Long = 0L
@volatile private var _mailbox: AnyRef = _
@@ -678,7 +677,7 @@ class LocalActorRef private[akka](
// instance elegible for garbage collection
private val actorSelfFields = findActorSelfField(actor.getClass)
- if (runActorInitialization && !isDeserialized) initializeActorInstance
+ if (runActorInitialization) initializeActorInstance
private[akka] def this(clazz: Class[_ <: Actor]) = this(Left(Some(clazz)))
private[akka] def this(factory: () => Actor) = this(Right(Some(factory)))
@@ -696,7 +695,6 @@ class LocalActorRef private[akka](
__hotswap: Option[PartialFunction[Any, Unit]],
__factory: () => Actor) = {
this(__factory)
- isDeserialized = true
_uuid = __uuid
id = __id
homeAddress = (__hostname, __port)
From 6d0ce27983945388390147110439dabb78b541b6 Mon Sep 17 00:00:00 2001
From: ticktock
Date: Tue, 28 Sep 2010 09:49:58 -0400
Subject: [PATCH 31/82] Initial Sketch of Persistence Compatibility Tests
---
.../src/test/scala/RefStorageBackendTest.scala | 3 +--
.../test/scala/VoldemortStorageBackendCompatibilityTest.scala | 4 +++-
project/build/AkkaProject.scala | 2 +-
3 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/akka-persistence/akka-persistence-common/src/test/scala/RefStorageBackendTest.scala b/akka-persistence/akka-persistence-common/src/test/scala/RefStorageBackendTest.scala
index 9625f45ebd..2a4cf85f21 100644
--- a/akka-persistence/akka-persistence-common/src/test/scala/RefStorageBackendTest.scala
+++ b/akka-persistence/akka-persistence-common/src/test/scala/RefStorageBackendTest.scala
@@ -13,9 +13,8 @@ import org.scalatest.{Suite, BeforeAndAfterEach, Spec}
/**
* Implementation Compatibility test for PersistentRef backend implementations.
*/
-@RunWith(classOf[JUnitRunner])
+
trait RefStorageBackendTest extends Spec with ShouldMatchers with BeforeAndAfterEach with Logging {
- this: Spec =>
def storage: RefStorageBackend[Array[Byte]]
def dropRefs: Unit
diff --git a/akka-persistence/akka-persistence-voldemort/src/test/scala/VoldemortStorageBackendCompatibilityTest.scala b/akka-persistence/akka-persistence-voldemort/src/test/scala/VoldemortStorageBackendCompatibilityTest.scala
index 095927e8ae..16d0a0c572 100644
--- a/akka-persistence/akka-persistence-voldemort/src/test/scala/VoldemortStorageBackendCompatibilityTest.scala
+++ b/akka-persistence/akka-persistence-voldemort/src/test/scala/VoldemortStorageBackendCompatibilityTest.scala
@@ -9,7 +9,9 @@ import org.scalatest.Spec
@RunWith(classOf[JUnitRunner])
class VoldemortStorageBackendCompatibilityTest extends RefStorageBackendTest with EmbeddedVoldemort {
- def dropRefs: Unit = {}
+ def dropRefs: Unit = {
+ //drop Refs Impl
+ }
def storage: RefStorageBackend[Array[Byte]] = {VoldemortStorageBackend}
diff --git a/project/build/AkkaProject.scala b/project/build/AkkaProject.scala
index a1c2a9fdf6..3fc6df6617 100644
--- a/project/build/AkkaProject.scala
+++ b/project/build/AkkaProject.scala
@@ -595,7 +595,7 @@ class AkkaParentProject(info: ProjectInfo) extends DefaultProject(info) {
val dbcp = Dependencies.dbcp
val sjson = Dependencies.sjson_test
- override def testOptions = createTestFilter( _.endsWith("Suite"))
+ override def testOptions = createTestFilter({ s:String=> s.endsWith("Suite") || s.endsWith("Test")})
}
From c8480412b7183ec3a2a580b365930f0c5483fc6e Mon Sep 17 00:00:00 2001
From: Viktor Klang
Date: Tue, 28 Sep 2010 16:30:58 +0200
Subject: [PATCH 32/82] Removing runActorInitialization volatile field, replace
with isRunning check
---
akka-actor/src/main/scala/actor/ActorRef.scala | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/akka-actor/src/main/scala/actor/ActorRef.scala b/akka-actor/src/main/scala/actor/ActorRef.scala
index 3fdc39d03e..e6ee2a4c66 100644
--- a/akka-actor/src/main/scala/actor/ActorRef.scala
+++ b/akka-actor/src/main/scala/actor/ActorRef.scala
@@ -666,7 +666,6 @@ class LocalActorRef private[akka](
@volatile private[akka] var _linkedActors: Option[ConcurrentHashMap[Uuid, ActorRef]] = None
@volatile private[akka] var _supervisor: Option[ActorRef] = None
@volatile private var isInInitialization = false
- @volatile private var runActorInitialization = false
@volatile private var maxNrOfRetriesCount: Int = 0
@volatile private var restartsWithinTimeRangeTimestamp: Long = 0L
@volatile private var _mailbox: AnyRef = _
@@ -677,7 +676,8 @@ class LocalActorRef private[akka](
// instance elegible for garbage collection
private val actorSelfFields = findActorSelfField(actor.getClass)
- if (runActorInitialization) initializeActorInstance
+ //If it was started inside "newActor", initialize it
+ if (isRunning) initializeActorInstance
private[akka] def this(clazz: Class[_ <: Actor]) = this(Left(Some(clazz)))
private[akka] def this(factory: () => Actor) = this(Right(Some(factory)))
@@ -812,7 +812,6 @@ class LocalActorRef private[akka](
}
_status = ActorRefStatus.RUNNING
if (!isInInitialization) initializeActorInstance
- else runActorInitialization = true
}
this
}
From 6157a903ccbd65226817d29e8177f9a008e740a0 Mon Sep 17 00:00:00 2001
From: ticktock
Date: Tue, 28 Sep 2010 18:38:15 -0400
Subject: [PATCH 33/82] Persistence Compatibility Test Harness and Voldemort
Implementation
Kept each of the datastructure test classes in seperate files as comprehensive tests will probably be relatively long
---
.../test/scala/MapStorageBackendTest.scala | 35 +++++++++++++++
.../test/scala/QueueStorageBackendTest.scala | 35 +++++++++++++++
.../test/scala/RefStorageBackendTest.scala | 6 +--
.../scala/SortedSetStorageBackendTest.scala | 35 +++++++++++++++
.../test/scala/VectorStorageBackendTest.scala | 35 +++++++++++++++
...emortStorageBackendCompatibilityTest.scala | 45 ++++++++++++++++---
6 files changed, 180 insertions(+), 11 deletions(-)
create mode 100644 akka-persistence/akka-persistence-common/src/test/scala/MapStorageBackendTest.scala
create mode 100644 akka-persistence/akka-persistence-common/src/test/scala/QueueStorageBackendTest.scala
create mode 100644 akka-persistence/akka-persistence-common/src/test/scala/SortedSetStorageBackendTest.scala
create mode 100644 akka-persistence/akka-persistence-common/src/test/scala/VectorStorageBackendTest.scala
diff --git a/akka-persistence/akka-persistence-common/src/test/scala/MapStorageBackendTest.scala b/akka-persistence/akka-persistence-common/src/test/scala/MapStorageBackendTest.scala
new file mode 100644
index 0000000000..aa9a417094
--- /dev/null
+++ b/akka-persistence/akka-persistence-common/src/test/scala/MapStorageBackendTest.scala
@@ -0,0 +1,35 @@
+/**
+ * Copyright (C) 2009-2010 Scalable Solutions AB
+ */
+
+package se.scalablesolutions.akka.persistence.common
+
+import org.scalatest.matchers.ShouldMatchers
+import se.scalablesolutions.akka.util.Logging
+import org.scalatest.{BeforeAndAfterEach, Spec}
+
+/**
+ * Implementation Compatibility test for PersistentMap backend implementations.
+ */
+
+trait MapStorageBackendTest extends Spec with ShouldMatchers with BeforeAndAfterEach with Logging {
+ def storage: MapStorageBackend[Array[Byte], Array[Byte]]
+
+ def dropMaps: Unit
+
+ override def beforeEach = {
+ log.info("beforeEach: dropping maps")
+ dropMaps
+ }
+
+ override def afterEach = {
+ log.info("afterEach: dropping maps")
+ dropMaps
+ }
+
+
+ describe("A Properly functioning MapStorageBackend") {
+
+ }
+
+}
\ No newline at end of file
diff --git a/akka-persistence/akka-persistence-common/src/test/scala/QueueStorageBackendTest.scala b/akka-persistence/akka-persistence-common/src/test/scala/QueueStorageBackendTest.scala
new file mode 100644
index 0000000000..7b2acc22b1
--- /dev/null
+++ b/akka-persistence/akka-persistence-common/src/test/scala/QueueStorageBackendTest.scala
@@ -0,0 +1,35 @@
+/**
+ * Copyright (C) 2009-2010 Scalable Solutions AB
+ */
+
+package se.scalablesolutions.akka.persistence.common
+
+import org.scalatest.matchers.ShouldMatchers
+import se.scalablesolutions.akka.util.Logging
+import org.scalatest.{BeforeAndAfterEach, Spec}
+
+/**
+ * Implementation Compatibility test for PersistentQueue backend implementations.
+ */
+
+trait QueueStorageBackendTest extends Spec with ShouldMatchers with BeforeAndAfterEach with Logging {
+ def storage: QueueStorageBackend[Array[Byte]]
+
+ def dropQueues: Unit
+
+ override def beforeEach = {
+ log.info("beforeEach: dropping queues")
+ dropQueues
+ }
+
+ override def afterEach = {
+ log.info("afterEach: dropping queues")
+ dropQueues
+ }
+
+
+ describe("A Properly functioning QueueStorage Backend") {
+
+ }
+
+}
\ No newline at end of file
diff --git a/akka-persistence/akka-persistence-common/src/test/scala/RefStorageBackendTest.scala b/akka-persistence/akka-persistence-common/src/test/scala/RefStorageBackendTest.scala
index 2a4cf85f21..96451bc063 100644
--- a/akka-persistence/akka-persistence-common/src/test/scala/RefStorageBackendTest.scala
+++ b/akka-persistence/akka-persistence-common/src/test/scala/RefStorageBackendTest.scala
@@ -4,11 +4,9 @@
package se.scalablesolutions.akka.persistence.common
-import org.scalatest.junit.JUnitRunner
-import org.junit.runner.RunWith
import org.scalatest.matchers.ShouldMatchers
import se.scalablesolutions.akka.util.Logging
-import org.scalatest.{Suite, BeforeAndAfterEach, Spec}
+import org.scalatest.{BeforeAndAfterEach, Spec}
/**
* Implementation Compatibility test for PersistentRef backend implementations.
@@ -30,7 +28,7 @@ trait RefStorageBackendTest extends Spec with ShouldMatchers with BeforeAndAfter
}
- describe("A Properly functioning RefStorage Backend") {
+ describe("A Properly functioning RefStorageBackend") {
it("should successfully insert ref storage") {
val name = "RefStorageTest #1"
val value = name.getBytes
diff --git a/akka-persistence/akka-persistence-common/src/test/scala/SortedSetStorageBackendTest.scala b/akka-persistence/akka-persistence-common/src/test/scala/SortedSetStorageBackendTest.scala
new file mode 100644
index 0000000000..2a9d3ab324
--- /dev/null
+++ b/akka-persistence/akka-persistence-common/src/test/scala/SortedSetStorageBackendTest.scala
@@ -0,0 +1,35 @@
+/**
+ * Copyright (C) 2009-2010 Scalable Solutions AB
+ */
+
+package se.scalablesolutions.akka.persistence.common
+
+import org.scalatest.matchers.ShouldMatchers
+import se.scalablesolutions.akka.util.Logging
+import org.scalatest.{BeforeAndAfterEach, Spec}
+
+/**
+ * Implementation Compatibility test for PersistentSortedSet backend implementations.
+ */
+
+trait SortedSetStorageBackendTest extends Spec with ShouldMatchers with BeforeAndAfterEach with Logging {
+ def storage: SortedSetStorageBackend[Array[Byte]]
+
+ def dropSortedSets: Unit
+
+ override def beforeEach = {
+ log.info("beforeEach: dropping sorted sets")
+ dropSortedSets
+ }
+
+ override def afterEach = {
+ log.info("afterEach: dropping sorted sets")
+ dropSortedSets
+ }
+
+
+ describe("A Properly functioning SortedSetStorageBackend Backend") {
+
+ }
+
+}
\ No newline at end of file
diff --git a/akka-persistence/akka-persistence-common/src/test/scala/VectorStorageBackendTest.scala b/akka-persistence/akka-persistence-common/src/test/scala/VectorStorageBackendTest.scala
new file mode 100644
index 0000000000..8b0008ea5a
--- /dev/null
+++ b/akka-persistence/akka-persistence-common/src/test/scala/VectorStorageBackendTest.scala
@@ -0,0 +1,35 @@
+/**
+ * Copyright (C) 2009-2010 Scalable Solutions AB
+ */
+
+package se.scalablesolutions.akka.persistence.common
+
+import org.scalatest.matchers.ShouldMatchers
+import se.scalablesolutions.akka.util.Logging
+import org.scalatest.{BeforeAndAfterEach, Spec}
+
+/**
+ * Implementation Compatibility test for PersistentVector backend implementations.
+ */
+
+trait VectorStorageBackendTest extends Spec with ShouldMatchers with BeforeAndAfterEach with Logging {
+ def storage: VectorStorageBackend[Array[Byte]]
+
+ def dropVectors: Unit
+
+ override def beforeEach = {
+ log.info("beforeEach: dropping vectors")
+ dropVectors
+ }
+
+ override def afterEach = {
+ log.info("afterEach: dropping vectors")
+ dropVectors
+ }
+
+
+ describe("A Properly functioning VectorStorageBackend") {
+
+ }
+
+}
\ No newline at end of file
diff --git a/akka-persistence/akka-persistence-voldemort/src/test/scala/VoldemortStorageBackendCompatibilityTest.scala b/akka-persistence/akka-persistence-voldemort/src/test/scala/VoldemortStorageBackendCompatibilityTest.scala
index 16d0a0c572..a7bcd9afff 100644
--- a/akka-persistence/akka-persistence-voldemort/src/test/scala/VoldemortStorageBackendCompatibilityTest.scala
+++ b/akka-persistence/akka-persistence-voldemort/src/test/scala/VoldemortStorageBackendCompatibilityTest.scala
@@ -3,16 +3,47 @@ package se.scalablesolutions.akka.persistence.voldemort
import org.junit.runner.RunWith
import org.scalatest.junit.JUnitRunner
-import se.scalablesolutions.akka.persistence.common.{RefStorageBackend, RefStorageBackendTest}
-import org.scalatest.Spec
-
+import se.scalablesolutions.akka.persistence.common.{QueueStorageBackendTest, VectorStorageBackendTest, MapStorageBackendTest, RefStorageBackendTest}
@RunWith(classOf[JUnitRunner])
-class VoldemortStorageBackendCompatibilityTest extends RefStorageBackendTest with EmbeddedVoldemort {
- def dropRefs: Unit = {
+class VoldemortRefStorageBackendTest extends RefStorageBackendTest with EmbeddedVoldemort {
+ def dropRefs = {
//drop Refs Impl
}
- def storage: RefStorageBackend[Array[Byte]] = {VoldemortStorageBackend}
-}
\ No newline at end of file
+ def storage = VoldemortStorageBackend
+}
+
+@RunWith(classOf[JUnitRunner])
+class VoldemortMapStorageBackendTest extends MapStorageBackendTest with EmbeddedVoldemort {
+ def dropMaps = {
+ //drop Maps Impl
+ }
+
+
+ def storage = VoldemortStorageBackend
+}
+
+@RunWith(classOf[JUnitRunner])
+class VoldemortVectorStorageBackendTest extends VectorStorageBackendTest with EmbeddedVoldemort {
+ def dropVectors = {
+ //drop Maps Impl
+ }
+
+
+ def storage = VoldemortStorageBackend
+}
+
+
+@RunWith(classOf[JUnitRunner])
+class VoldemortQueueStorageBackendTest extends QueueStorageBackendTest with EmbeddedVoldemort {
+ def dropQueues = {
+ //drop Maps Impl
+ }
+
+
+ def storage = VoldemortStorageBackend
+}
+
+
From e88dec563928d9141589ade8b363615a2ed5c59c Mon Sep 17 00:00:00 2001
From: ticktock
Date: Tue, 28 Sep 2010 22:06:06 -0400
Subject: [PATCH 34/82] Initial Spec for MapStorageBackend
---
.../test/scala/MapStorageBackendTest.scala | 108 ++++++++++++++++++
.../src/test/scala/EmbeddedVoldemort.scala | 10 +-
...emortStorageBackendCompatibilityTest.scala | 8 +-
3 files changed, 118 insertions(+), 8 deletions(-)
diff --git a/akka-persistence/akka-persistence-common/src/test/scala/MapStorageBackendTest.scala b/akka-persistence/akka-persistence-common/src/test/scala/MapStorageBackendTest.scala
index aa9a417094..5bab5b8939 100644
--- a/akka-persistence/akka-persistence-common/src/test/scala/MapStorageBackendTest.scala
+++ b/akka-persistence/akka-persistence-common/src/test/scala/MapStorageBackendTest.scala
@@ -7,6 +7,8 @@ package se.scalablesolutions.akka.persistence.common
import org.scalatest.matchers.ShouldMatchers
import se.scalablesolutions.akka.util.Logging
import org.scalatest.{BeforeAndAfterEach, Spec}
+import scala.util.Random
+import collection.immutable.{HashMap, HashSet}
/**
* Implementation Compatibility test for PersistentMap backend implementations.
@@ -29,6 +31,112 @@ trait MapStorageBackendTest extends Spec with ShouldMatchers with BeforeAndAfter
describe("A Properly functioning MapStorageBackend") {
+ it("should remove map storage properly") {
+ val mapName = "removeTest"
+ val mkey = "removeTestKey".getBytes
+ val value = "removeTestValue".getBytes
+
+ storage.insertMapStorageEntryFor(mapName, mkey, value)
+ storage.getMapStorageEntryFor(mapName, mkey).isDefined should be(true)
+ storage.removeMapStorageFor(mapName, mkey)
+ storage.getMapStorageEntryFor(mapName, mkey) should be(None)
+
+ storage.insertMapStorageEntryFor(mapName, mkey, value)
+ storage.getMapStorageEntryFor(mapName, mkey).isDefined should be(true)
+ storage.removeMapStorageFor(mapName)
+ storage.getMapStorageEntryFor(mapName, mkey) should be(None)
+ }
+
+ it("should insert a single map storage element properly") {
+ val mapName = "insertSingleTest"
+ val mkey = "insertSingleTestKey".getBytes
+ val value = "insertSingleTestValue".getBytes
+
+ storage.insertMapStorageEntryFor(mapName, mkey, value)
+ storage.getMapStorageEntryFor(mapName, mkey).get should be(value)
+ storage.removeMapStorageFor(mapName, mkey)
+ storage.getMapStorageEntryFor(mapName, mkey) should be(None)
+
+ storage.insertMapStorageEntryFor(mapName, mkey, value)
+ storage.getMapStorageEntryFor(mapName, mkey).get should be(value)
+ storage.removeMapStorageFor(mapName)
+ storage.getMapStorageEntryFor(mapName, mkey) should be(None)
+ }
+
+
+ it("should insert multiple map storage elements properly") {
+ val mapName = "insertMultipleTest"
+ val rand = new Random(2).nextInt(100)
+ val entries = (1 to rand).toList.map {
+ index =>
+ (("insertMultipleTestKey" + index).getBytes -> ("insertMutlipleTestValue" + index).getBytes)
+ }
+
+ storage.insertMapStorageEntriesFor(mapName, entries)
+ entries foreach {
+ _ match {
+ case (mkey, value) => {
+ storage.getMapStorageEntryFor(mapName, mkey).isDefined should be(true)
+ storage.getMapStorageEntryFor(mapName, mkey).get should be(value)
+ }
+ }
+ }
+ storage.removeMapStorageFor(mapName)
+ entries foreach {
+ _ match {
+ case (mkey, value) => {
+ storage.getMapStorageEntryFor(mapName, mkey) should be(None)
+ }
+ }
+ }
+ }
+
+
+ it("should accurately track the number of key value pairs in a map") {
+ val mapName = "sizeTest"
+ val rand = new Random(3).nextInt(100)
+ val entries = (1 to rand).toList.map {
+ index =>
+ (("sizeTestKey" + index).getBytes -> ("sizeTestValue" + index).getBytes)
+ }
+
+ storage.insertMapStorageEntriesFor(mapName, entries)
+ storage.getMapStorageSizeFor(mapName) should be(rand)
+ }
+
+
+
+ it("should return all the key value pairs in the map (in the correct order?) when getMapStorageFor(name) is called") {
+ val mapName = "allTest"
+ val rand = new Random(3).nextInt(100)
+ val entries = (1 to rand).toList.map {
+ index =>
+ (("allTestKey" + index).getBytes -> ("allTestValue" + index).getBytes)
+ }
+
+ storage.insertMapStorageEntriesFor(mapName, entries)
+ val retrieved = storage.getMapStorageFor(mapName)
+ retrieved.size should be(rand)
+ entries.size should be(rand)
+
+
+ val entryMap = new HashMap[String, String] ++ entries.map {_ match {case (k, v) => (new String(k), new String(v))}}
+ val retrievedMap = new HashMap[String, String] ++ entries.map {_ match {case (k, v) => (new String(k), new String(v))}}
+
+ entryMap should equal(retrievedMap)
+ //Should the ordering of key-vals returned be enforced?
+ //ordered by key?
+ //using what comaparison?
+
+ }
+
+ it("should not throw an exception when size is called on a non existent map?") {
+ storage.getMapStorageSizeFor("nonExistent") should be(0)
+ }
+
+ it("should behave properly when getMapStorageRange is called?") {
+ //No current code calls getMapStorageRangeFor
+ }
}
diff --git a/akka-persistence/akka-persistence-voldemort/src/test/scala/EmbeddedVoldemort.scala b/akka-persistence/akka-persistence-voldemort/src/test/scala/EmbeddedVoldemort.scala
index ce87309fb9..d0f40f1a03 100644
--- a/akka-persistence/akka-persistence-voldemort/src/test/scala/EmbeddedVoldemort.scala
+++ b/akka-persistence/akka-persistence-voldemort/src/test/scala/EmbeddedVoldemort.scala
@@ -1,20 +1,20 @@
package se.scalablesolutions.akka.persistence.voldemort
-import org.scalatest.matchers.ShouldMatchers
import voldemort.server.{VoldemortServer, VoldemortConfig}
-import org.scalatest.{Suite, BeforeAndAfterAll, FunSuite}
+import org.scalatest.{Suite, BeforeAndAfterAll}
import org.junit.runner.RunWith
import org.scalatest.junit.JUnitRunner
-import voldemort.utils.Utils
import java.io.File
import se.scalablesolutions.akka.util.{Logging}
import collection.JavaConversions
import voldemort.store.memory.InMemoryStorageConfiguration
+import voldemort.client.protocol.admin.{AdminClientConfig, AdminClient}
+
-@RunWith(classOf[JUnitRunner])
trait EmbeddedVoldemort extends BeforeAndAfterAll with Logging {
this: Suite =>
var server: VoldemortServer = null
+ var admin: AdminClient = null
override protected def beforeAll(): Unit = {
@@ -28,6 +28,7 @@ trait EmbeddedVoldemort extends BeforeAndAfterAll with Logging {
server = new VoldemortServer(config)
server.start
VoldemortStorageBackend.initStoreClients
+ admin = new AdminClient(VoldemortStorageBackend.clientConfig.getProperty(VoldemortStorageBackend.bootstrapUrlsProp), new AdminClientConfig)
log.info("Started")
} catch {
case e => log.error(e, "Error Starting Voldemort")
@@ -36,6 +37,7 @@ trait EmbeddedVoldemort extends BeforeAndAfterAll with Logging {
}
override protected def afterAll(): Unit = {
+ admin.stop
server.stop
}
}
\ No newline at end of file
diff --git a/akka-persistence/akka-persistence-voldemort/src/test/scala/VoldemortStorageBackendCompatibilityTest.scala b/akka-persistence/akka-persistence-voldemort/src/test/scala/VoldemortStorageBackendCompatibilityTest.scala
index a7bcd9afff..b9b3ea4ed1 100644
--- a/akka-persistence/akka-persistence-voldemort/src/test/scala/VoldemortStorageBackendCompatibilityTest.scala
+++ b/akka-persistence/akka-persistence-voldemort/src/test/scala/VoldemortStorageBackendCompatibilityTest.scala
@@ -8,7 +8,7 @@ import se.scalablesolutions.akka.persistence.common.{QueueStorageBackendTest, Ve
@RunWith(classOf[JUnitRunner])
class VoldemortRefStorageBackendTest extends RefStorageBackendTest with EmbeddedVoldemort {
def dropRefs = {
- //drop Refs Impl
+ admin.truncate(0, VoldemortStorageBackend.refStore)
}
@@ -18,7 +18,7 @@ class VoldemortRefStorageBackendTest extends RefStorageBackendTest with Embedded
@RunWith(classOf[JUnitRunner])
class VoldemortMapStorageBackendTest extends MapStorageBackendTest with EmbeddedVoldemort {
def dropMaps = {
- //drop Maps Impl
+ admin.truncate(0, VoldemortStorageBackend.mapStore)
}
@@ -28,7 +28,7 @@ class VoldemortMapStorageBackendTest extends MapStorageBackendTest with Embedded
@RunWith(classOf[JUnitRunner])
class VoldemortVectorStorageBackendTest extends VectorStorageBackendTest with EmbeddedVoldemort {
def dropVectors = {
- //drop Maps Impl
+ admin.truncate(0, VoldemortStorageBackend.vectorStore)
}
@@ -39,7 +39,7 @@ class VoldemortVectorStorageBackendTest extends VectorStorageBackendTest with Em
@RunWith(classOf[JUnitRunner])
class VoldemortQueueStorageBackendTest extends QueueStorageBackendTest with EmbeddedVoldemort {
def dropQueues = {
- //drop Maps Impl
+ admin.truncate(0, VoldemortStorageBackend.queueStore)
}
From 5e0dfea15c5579e85ffcb185f2c5e8f8ca00c3d0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jonas=20Bon=C3=A9r?=
Date: Wed, 29 Sep 2010 10:30:05 +0200
Subject: [PATCH 35/82] Refactored ExecutableMailbox to make it accessible for
other implementations
---
.../ExecutorBasedEventDrivenDispatcher.scala | 147 +++++++++++-------
...sedEventDrivenWorkStealingDispatcher.scala | 13 ++
.../main/scala/dispatch/HawtDispatcher.scala | 7 +-
.../main/scala/dispatch/MailboxHandling.scala | 12 +-
.../scala/DispatcherSpringFeatureTest.scala | 5 +-
5 files changed, 109 insertions(+), 75 deletions(-)
diff --git a/akka-actor/src/main/scala/dispatch/ExecutorBasedEventDrivenDispatcher.scala b/akka-actor/src/main/scala/dispatch/ExecutorBasedEventDrivenDispatcher.scala
index d36af50ad6..1203d32fde 100644
--- a/akka-actor/src/main/scala/dispatch/ExecutorBasedEventDrivenDispatcher.scala
+++ b/akka-actor/src/main/scala/dispatch/ExecutorBasedEventDrivenDispatcher.scala
@@ -5,6 +5,7 @@
package se.scalablesolutions.akka.dispatch
import se.scalablesolutions.akka.actor.{ActorRef, IllegalActorStateException}
+import se.scalablesolutions.akka.util.ReflectiveAccess.EnterpriseModule
import java.util.Queue
import java.util.concurrent.{RejectedExecutionException, ConcurrentLinkedQueue, LinkedBlockingQueue}
@@ -84,77 +85,25 @@ class ExecutorBasedEventDrivenDispatcher(
val mailboxType = Some(_mailboxType)
- @volatile private var active = false
+ @volatile private[akka] var active = false
val name = "akka:event-driven:dispatcher:" + _name
init
- /**
- * This is the behavior of an ExecutorBasedEventDrivenDispatchers mailbox
- */
- trait ExecutableMailbox extends Runnable { self: MessageQueue =>
- final def run = {
- val reschedule = try {
- processMailbox()
- } finally {
- dispatcherLock.unlock()
- }
- if (reschedule || !self.isEmpty) registerForExecution(self)
- }
-
- /**
- * Process the messages in the mailbox
- *
- * @return true if the processing finished before the mailbox was empty, due to the throughput constraint
- */
- final def processMailbox(): Boolean = {
- var nextMessage = self.dequeue
- if (nextMessage ne null) {
- val throttle = throughput > 0
- var processedMessages = 0
- val isDeadlineEnabled = throttle && throughputDeadlineTime > 0
- val started = if (isDeadlineEnabled) System.currentTimeMillis else 0
- do {
- nextMessage.invoke
-
- if (nextMessage.receiver.isBeingRestarted)
- return !self.isEmpty
-
- if (throttle) { // Will be elided when false
- processedMessages += 1
- if ((processedMessages >= throughput) ||
- (isDeadlineEnabled && (System.currentTimeMillis - started) >= throughputDeadlineTime)) // If we're throttled, break out
- return !self.isEmpty
- }
- nextMessage = self.dequeue
- } while (nextMessage ne null)
- }
- false
- }
- }
-
def dispatch(invocation: MessageInvocation) = {
val mbox = getMailbox(invocation.receiver)
mbox enqueue invocation
- registerForExecution(mbox)
+ mbox.registerForExecution
}
- def registerForExecution(mailbox: MessageQueue with ExecutableMailbox): Unit = if (active) {
- if (mailbox.dispatcherLock.tryLock()) {
- try {
- executor execute mailbox
- } catch {
- case e: RejectedExecutionException =>
- mailbox.dispatcherLock.unlock()
- throw e
- }
- }
- } else log.warning("%s is shut down,\n\tignoring the rest of the messages in the mailbox of\n\t%s", toString, mailbox)
-
/**
* @return the mailbox associated with the actor
*/
- private def getMailbox(receiver: ActorRef) = receiver.mailbox.asInstanceOf[MessageQueue with ExecutableMailbox]
+ private def getMailbox(receiver: ActorRef) = {
+ val mb = receiver.mailbox.asInstanceOf[MessageQueue with ExecutableMailbox]
+ mb.register(this)
+ mb
+ }
override def mailboxSize(actorRef: ActorRef) = getMailbox(actorRef).size
@@ -166,6 +115,19 @@ class ExecutorBasedEventDrivenDispatcher(
new DefaultBoundedMessageQueue(cap, pushTimeOut, blocking) with ExecutableMailbox
}
+ /**
+ * Creates and returns a durable mailbox for the given actor.
+ */
+ def createDurableMailbox(actorRef: ActorRef, mailboxType: DurableMailboxType): AnyRef = mailboxType match {
+ // FIXME make generic (work for TypedActor as well)
+ case FileBasedDurableMailbox(serializer) => EnterpriseModule.createFileBasedMailbox(actorRef).asInstanceOf[MessageQueue]
+ case ZooKeeperBasedDurableMailbox(serializer) => EnterpriseModule.createZooKeeperBasedMailbox(actorRef).asInstanceOf[MessageQueue]
+ case BeanstalkBasedDurableMailbox(serializer) => EnterpriseModule.createBeanstalkBasedMailbox(actorRef).asInstanceOf[MessageQueue]
+ case RedisBasedDurableMailbox(serializer) => EnterpriseModule.createRedisBasedMailbox(actorRef).asInstanceOf[MessageQueue]
+ case AMQPBasedDurableMailbox(serializer) => throw new UnsupportedOperationException("AMQPBasedDurableMailbox is not yet supported")
+ case JMSBasedDurableMailbox(serializer) => throw new UnsupportedOperationException("JMSBasedDurableMailbox is not yet supported")
+ }
+
def start = if (!active) {
log.debug("Starting up %s\n\twith throughput [%d]", toString, throughput)
active = true
@@ -191,4 +153,69 @@ class ExecutorBasedEventDrivenDispatcher(
config(this)
buildThreadPool
}
-}
\ No newline at end of file
+}
+
+/**
+ * This is the behavior of an ExecutorBasedEventDrivenDispatchers mailbox.
+ */
+trait ExecutableMailbox extends Runnable { self: MessageQueue =>
+
+ private var _dispatcher: Option[ExecutorBasedEventDrivenDispatcher] = None
+
+ def register(md: ExecutorBasedEventDrivenDispatcher) = _dispatcher = Some(md)
+ def dispatcher: ExecutorBasedEventDrivenDispatcher = _dispatcher.getOrElse(
+ throw new IllegalActorStateException("mailbox.register(dispatcher) has not been invoked"))
+
+ final def run = {
+ val reschedule = try {
+ processMailbox()
+ } finally {
+ dispatcherLock.unlock()
+ }
+ if (reschedule || !self.isEmpty) registerForExecution
+ }
+
+ /**
+ * Process the messages in the mailbox
+ *
+ * @return true if the processing finished before the mailbox was empty, due to the throughput constraint
+ */
+ final def processMailbox(): Boolean = {
+ var nextMessage = self.dequeue
+ if (nextMessage ne null) {
+ val throttle = dispatcher.throughput > 0
+ var processedMessages = 0
+ val isDeadlineEnabled = throttle && dispatcher.throughputDeadlineTime > 0
+ val started = if (isDeadlineEnabled) System.currentTimeMillis else 0
+ do {
+ nextMessage.invoke
+
+ if (nextMessage.receiver.isBeingRestarted)
+ return !self.isEmpty
+
+ if (throttle) { // Will be elided when false
+ processedMessages += 1
+ if ((processedMessages >= dispatcher.throughput) ||
+ (isDeadlineEnabled && (System.currentTimeMillis - started) >= dispatcher.throughputDeadlineTime)) // If we're throttled, break out
+ return !self.isEmpty
+ }
+ nextMessage = self.dequeue
+ } while (nextMessage ne null)
+ }
+ false
+ }
+
+
+ def registerForExecution: Unit = if (dispatcher.active) {
+ if (dispatcherLock.tryLock()) {
+ try {
+ dispatcher.execute(this)
+ } catch {
+ case e: RejectedExecutionException =>
+ dispatcherLock.unlock()
+ throw e
+ }
+ }
+ } else dispatcher.log.warning("%s is shut down,\n\tignoring the rest of the messages in the mailbox of\n\t%s", toString, this)
+}
+
diff --git a/akka-actor/src/main/scala/dispatch/ExecutorBasedEventDrivenWorkStealingDispatcher.scala b/akka-actor/src/main/scala/dispatch/ExecutorBasedEventDrivenWorkStealingDispatcher.scala
index a5ed113b97..eb949958c9 100644
--- a/akka-actor/src/main/scala/dispatch/ExecutorBasedEventDrivenWorkStealingDispatcher.scala
+++ b/akka-actor/src/main/scala/dispatch/ExecutorBasedEventDrivenWorkStealingDispatcher.scala
@@ -215,6 +215,19 @@ class ExecutorBasedEventDrivenWorkStealingDispatcher(
}
}
+ /**
+ * Creates and returns a durable mailbox for the given actor.
+ */
+ protected def createDurableMailbox(actorRef: ActorRef, mailboxType: DurableMailboxType): AnyRef = mailboxType match {
+ // FIXME make generic (work for TypedActor as well)
+ case FileBasedDurableMailbox(serializer) => throw new UnsupportedOperationException("FileBasedDurableMailbox is not yet supported for ExecutorBasedEventDrivenWorkStealingDispatcher")
+ case ZooKeeperBasedDurableMailbox(serializer) => throw new UnsupportedOperationException("ZooKeeperBasedDurableMailbox is not yet supported for ExecutorBasedEventDrivenWorkStealingDispatcher")
+ case BeanstalkBasedDurableMailbox(serializer) => throw new UnsupportedOperationException("BeanstalkBasedDurableMailbox is not yet supported for ExecutorBasedEventDrivenWorkStealingDispatcher")
+ case RedisBasedDurableMailbox(serializer) => throw new UnsupportedOperationException("RedisBasedDurableMailbox is not yet supported for ExecutorBasedEventDrivenWorkStealingDispatcher")
+ case AMQPBasedDurableMailbox(serializer) => throw new UnsupportedOperationException("AMQPBasedDurableMailbox is not yet supported for ExecutorBasedEventDrivenWorkStealingDispatcher")
+ case JMSBasedDurableMailbox(serializer) => throw new UnsupportedOperationException("JMSBasedDurableMailbox is not yet supported for ExecutorBasedEventDrivenWorkStealingDispatcher")
+ }
+
override def register(actorRef: ActorRef) = {
verifyActorsAreOfSameType(actorRef)
pooledActors add actorRef
diff --git a/akka-actor/src/main/scala/dispatch/HawtDispatcher.scala b/akka-actor/src/main/scala/dispatch/HawtDispatcher.scala
index 549765d9fe..cb96b39a3b 100644
--- a/akka-actor/src/main/scala/dispatch/HawtDispatcher.scala
+++ b/akka-actor/src/main/scala/dispatch/HawtDispatcher.scala
@@ -172,7 +172,12 @@ class HawtDispatcher(val aggregate: Boolean = true, val parent: DispatchQueue =
def createTransientMailbox(actorRef: ActorRef, mailboxType: TransientMailboxType): AnyRef = null.asInstanceOf[AnyRef]
- override def toString = "HawtDispatchEventDrivenDispatcher"
+ /**
+ * Creates and returns a durable mailbox for the given actor.
+ */
+ protected def createDurableMailbox(actorRef: ActorRef, mailboxType: DurableMailboxType): AnyRef = null.asInstanceOf[AnyRef]
+
+ override def toString = "HawtDispatcher"
}
class HawtDispatcherMailbox(val queue: DispatchQueue) {
diff --git a/akka-actor/src/main/scala/dispatch/MailboxHandling.scala b/akka-actor/src/main/scala/dispatch/MailboxHandling.scala
index 360c8a143f..192313f178 100644
--- a/akka-actor/src/main/scala/dispatch/MailboxHandling.scala
+++ b/akka-actor/src/main/scala/dispatch/MailboxHandling.scala
@@ -101,15 +101,7 @@ trait MailboxFactory {
protected def createTransientMailbox(actorRef: ActorRef, mailboxType: TransientMailboxType): AnyRef
/**
- * Creates and returns a durable mailbox for the given actor.
+ * Creates and returns a durable mailbox for the given actor.
*/
- protected def createDurableMailbox(actorRef: ActorRef, mailboxType: DurableMailboxType): AnyRef = mailboxType match {
- // FIXME make generic (work for TypedActor as well)
- case FileBasedDurableMailbox(serializer) => EnterpriseModule.createFileBasedMailbox(actorRef).asInstanceOf[MessageQueue]
- case ZooKeeperBasedDurableMailbox(serializer) => EnterpriseModule.createZooKeeperBasedMailbox(actorRef).asInstanceOf[MessageQueue]
- case BeanstalkBasedDurableMailbox(serializer) => EnterpriseModule.createBeanstalkBasedMailbox(actorRef).asInstanceOf[MessageQueue]
- case RedisBasedDurableMailbox(serializer) => EnterpriseModule.createRedisBasedMailbox(actorRef).asInstanceOf[MessageQueue]
- case AMQPBasedDurableMailbox(serializer) => throw new UnsupportedOperationException("AMQPBasedDurableMailbox is not yet supported")
- case JMSBasedDurableMailbox(serializer) => throw new UnsupportedOperationException("JMSBasedDurableMailbox is not yet supported")
- }
+ protected def createDurableMailbox(actorRef: ActorRef, mailboxType: DurableMailboxType): AnyRef
}
\ No newline at end of file
diff --git a/akka-spring/src/test/scala/DispatcherSpringFeatureTest.scala b/akka-spring/src/test/scala/DispatcherSpringFeatureTest.scala
index 7d886c7fb0..51c8d2bd73 100644
--- a/akka-spring/src/test/scala/DispatcherSpringFeatureTest.scala
+++ b/akka-spring/src/test/scala/DispatcherSpringFeatureTest.scala
@@ -18,9 +18,6 @@ import org.springframework.core.io.{ClassPathResource, Resource}
import java.util.concurrent._
import se.scalablesolutions.akka.actor.{UntypedActor, Actor, ActorRef}
-
-
-
/**
* Tests for spring configuration of typed actors.
* @author michaelkober
@@ -109,7 +106,7 @@ class DispatcherSpringFeatureTest extends FeatureSpec with ShouldMatchers {
val context = new ClassPathXmlApplicationContext("/dispatcher-config.xml")
val dispatcher = context.getBean("hawt-dispatcher").asInstanceOf[HawtDispatcher]
assert(dispatcher ne null)
- assert(dispatcher.toString === "HawtDispatchEventDrivenDispatcher")
+ assert(dispatcher.toString === "HawtDispatcher")
assert(dispatcher.aggregate === false)
}
From 2be8b2bab51c5086fb27fa9445df49d2b14464a6 Mon Sep 17 00:00:00 2001
From: Debasish Ghosh
Date: Wed, 29 Sep 2010 15:06:31 +0530
Subject: [PATCH 36/82] refactoring to remove compiler warnings reported by
Viktor
---
.../akka-persistence-common/src/main/scala/Storage.scala | 7 +++----
.../src/main/scala/serialization/Serializable.scala | 1 -
2 files changed, 3 insertions(+), 5 deletions(-)
diff --git a/akka-persistence/akka-persistence-common/src/main/scala/Storage.scala b/akka-persistence/akka-persistence-common/src/main/scala/Storage.scala
index 77e40a6127..e75fd9581c 100644
--- a/akka-persistence/akka-persistence-common/src/main/scala/Storage.scala
+++ b/akka-persistence/akka-persistence-common/src/main/scala/Storage.scala
@@ -74,7 +74,6 @@ trait Storage {
private[akka] object PersistentMap {
// operations on the Map
sealed trait Op
- case object GET extends Op
case object PUT extends Op
case object REM extends Op
case object UPD extends Op
@@ -309,7 +308,7 @@ trait PersistentMapBinary extends PersistentMap[Array[Byte], Array[Byte]] {
.filter(k => existsInStorage(k).isDefined)
.map(k => ArraySeq(k: _*))
- (fromStorage -- inStorageRemovedInTx) ++ keysAdded.map { case (k, Some(v)) => (ArraySeq(k: _*), v) }
+ (fromStorage -- inStorageRemovedInTx) ++ keysAdded.map { case (k, v) => (ArraySeq(k: _*), v.get) }
}
override def slice(start: Option[Array[Byte]], finish: Option[Array[Byte]], count: Int): List[(Array[Byte], Array[Byte])] = try {
@@ -396,7 +395,7 @@ trait PersistentVector[T] extends IndexedSeq[T] with Transactional with Committa
def commit = {
for(entry <- appendOnlyTxLog) {
- entry match {
+ (entry: @unchecked) match {
case LogEntry(_, Some(v), ADD) => storage.insertVectorStorageEntryFor(uuid, v)
case LogEntry(Some(i), Some(v), UPD) => storage.updateVectorStorageEntryFor(uuid, i, v)
case LogEntry(_, _, POP) => //..
@@ -414,7 +413,7 @@ trait PersistentVector[T] extends IndexedSeq[T] with Transactional with Committa
var elemsStorage = ArrayBuffer(storage.getVectorStorageRangeFor(uuid, None, None, storage.getVectorStorageSizeFor(uuid)).reverse: _*)
for(entry <- appendOnlyTxLog) {
- entry match {
+ (entry: @unchecked) match {
case LogEntry(_, Some(v), ADD) => elemsStorage += v
case LogEntry(Some(i), Some(v), UPD) => elemsStorage.update(i, v)
case LogEntry(_, _, POP) => elemsStorage = elemsStorage.drop(1)
diff --git a/akka-remote/src/main/scala/serialization/Serializable.scala b/akka-remote/src/main/scala/serialization/Serializable.scala
index b15784f9ce..a939964420 100644
--- a/akka-remote/src/main/scala/serialization/Serializable.scala
+++ b/akka-remote/src/main/scala/serialization/Serializable.scala
@@ -9,7 +9,6 @@ import org.codehaus.jackson.map.ObjectMapper
import com.google.protobuf.Message
import reflect.Manifest
-import sbinary.DefaultProtocol
import java.io.{StringWriter, ByteArrayOutputStream, ObjectOutputStream}
From c245d330098624f4b46a3d0b6b11cdac13e6148f Mon Sep 17 00:00:00 2001
From: Debasish Ghosh
Date: Wed, 29 Sep 2010 18:29:19 +0530
Subject: [PATCH 37/82] new version of redisclient containing a redis based
persistent deque
---
.../2.8.0-2.0.1/redisclient-2.8.0-2.0.1.jar | Bin 0 -> 238314 bytes
.../2.8.0-2.0.1/redisclient-2.8.0-2.0.1.pom | 8 ++++++++
project/build/AkkaProject.scala | 2 +-
3 files changed, 9 insertions(+), 1 deletion(-)
create mode 100644 embedded-repo/com/redis/redisclient/2.8.0-2.0.1/redisclient-2.8.0-2.0.1.jar
create mode 100644 embedded-repo/com/redis/redisclient/2.8.0-2.0.1/redisclient-2.8.0-2.0.1.pom
diff --git a/embedded-repo/com/redis/redisclient/2.8.0-2.0.1/redisclient-2.8.0-2.0.1.jar b/embedded-repo/com/redis/redisclient/2.8.0-2.0.1/redisclient-2.8.0-2.0.1.jar
new file mode 100644
index 0000000000000000000000000000000000000000..7709ef140bfb09040b33d98c1e0cbb91011247b2
GIT binary patch
literal 238314
zcmWIWW@Zs#;9%fj*fr7CmH`QfFt9NAx`sIFdiuHP`#So0y1532==r++JH^28+4sz8
zA8%c~i@e^tTIbH3-yCFc#rVO~M^Bj;0=(HdHq|q|lV)IGkYr$B2!LBK70m(}1_p-Y
z{9OH_)RfF({m{JP(xl?#qRgaJ6}{w~#Ny)K$#1hS2Z$V-KYQKTNmut?EuEWR9JPJf
z+|#eDOSlg2iwoT%NW;pFPr
z+N60(bmy~#3)Sa0gq`-gcByBF-d^IvndIchKSl`CHt^UXbVBjja;U#Fk1hRbgMdDbTj=XhJIz2gixw)m!6
z=d6SZpZ}_YuFtLgiz`Jk+?H(@>V2f%zpy9ZkIKBG7Y~$ZRd^-}^*%l3uQ9*yC-bu7
z8uBLl9^K+NEuZOni03Z1p~u18g}zD!#(o;}!V0*1c5LC*{GNF#^wR%^Wz)9g<@-8q@jOYX`V)0sPq&)rR*fBf#}^ZV=fuuO1lcGSDIZ}DfufF
zm>&O@bJuMB?ptkb&1hW-!L)nK0e{n
z+p1fF4lkMVXV|Y?m3H%5TmH(+?)_2D5k^97B0NrAN?bD&1Gd)oTl0t)?{!S;Xj_>k
zaqc-&Q|9sQHjB?){`pGm`d+5{3jH1e4J(dqZu
zRGRCUfs$~i@s^{vO=8-z)dOCfXjU?6UZ-<7rmu#9y%rO^{=^ywGKNVvsJ)t5z)h_qS>wW4YNt8&}PCR~hIfe{`wduJOnHN5nCcJfW>-
zi(78Xwe=m}
zGnPZKO20N-)@$VJ`?PqmX$H?T8Fyv7%^&spI?sv8n!I3qoA)7V!)zwKhs86w_Ma)x
zzPEGbiTW39rF-tS2pzVax$7@0?-H-NZC_v6A9fOdVb=3sIF)s^QOFa?U)x>=#CMi^
z?|CfRd-h{<$@O~=^A2wJ+A<+PCGqpxReOUsZJu_#V4HMSn4_eqq^ga;Nw(+pdmp!O
zJ&2n5#Q%`9)xxJ&b5;gd@y*p(nExSHB>u7Wq|G-2%<_-r1@0(oD
zIlO3M{GE%H71K&srPxxgI22cYwYU;<^{b5UcfMoB#S6-XJEv}II&60Gc9{_og_`774iA3hd;@`_xZ%JOd-m(vaW
zv~K-S{84d1_16wIyQW8BAO0D}F5WUrjnjDLoWQD8$xrM-#Y?s>M=b*j1A{9EzT(9K
zrFcosDJ?EZEz%DH)p*Vj4x)(3%TG!5POU6fF@}^fQ$w=-g&jp~F9%J##-*$8`gCDP
z&caRG9&BzsvOpzcV#dbK_$zOXrYYXOnI^CDW3__Xgp5VLK7Stc8{LaEYj9dowt4ei
z>*w>T-|sB{_I&;Mct(*A9g2ZlYmYxUedrO--}OJ*3a0Da|GLBY^{lp3gD+Ejy*(c4
z8o6xVDdl{9(q6|0Q%=h!Mwq_aacJ85@OcIs(s^7j=e_ECbn&dS(qENqwPcUzx(}&t
zLZ^%OJx+UO@