1. Made LocalActorRef aware of replication

2. Added configuration for transaction log replication
3. Added replication schemes WriteThrough and WriteBehind
4. Refactored serializer creation and lookup in Actor.scala
5. Extended network protocol with replication strategy
6. Added BookKeeper management to tests
7. Improved logging and error messages
8. Removed ReplicatedActorRef
9. Added snapshot management to TransactionLog

Signed-off-by: Jonas Bonér <jonas@jonasboner.com>
This commit is contained in:
Jonas Bonér 2011-06-07 11:10:29 -07:00
parent 3d7a717b06
commit 04efc440d6
22 changed files with 6540 additions and 2183 deletions

View file

@ -4,20 +4,21 @@
package akka.serialization
import akka.dispatch.MessageInvocation
import akka.remote.protocol.RemoteProtocol._
import akka.remote.protocol.RemoteProtocol
import akka.config.Supervision._
import akka.actor.{ uuidFrom, newUuid }
import akka.actor._
import DeploymentConfig.{ ReplicationStrategy, Transient, WriteThrough, WriteBehind }
import akka.dispatch.MessageInvocation
import akka.util.ReflectiveAccess
import akka.remote.{ RemoteClientSettings, MessageSerializer }
import akka.remote.protocol.RemoteProtocol
import RemoteProtocol._
import scala.collection.immutable.Stack
import com.google.protobuf.ByteString
import akka.util.ReflectiveAccess
import java.net.InetSocketAddress
import akka.remote.{ RemoteClientSettings, MessageSerializer }
import com.google.protobuf.ByteString
/**
* Module for local actor serialization.
@ -31,19 +32,29 @@ object ActorSerialization {
def fromBinary[T <: Actor](bytes: Array[Byte])(implicit format: Serializer): ActorRef =
fromBinaryToLocalActorRef(bytes, None, format)
def toBinary[T <: Actor](a: ActorRef, serializeMailBox: Boolean = true)(implicit format: Serializer): Array[Byte] =
toSerializedActorRefProtocol(a, format, serializeMailBox).toByteArray
def toBinary[T <: Actor](
a: ActorRef,
serializeMailBox: Boolean = true,
replicationStrategy: ReplicationStrategy = Transient)(implicit format: Serializer): Array[Byte] =
toSerializedActorRefProtocol(a, format, serializeMailBox, replicationStrategy).toByteArray
// wrapper for implicits to be used by Java
def fromBinaryJ[T <: Actor](bytes: Array[Byte], format: Serializer): ActorRef =
fromBinary(bytes)(format)
// wrapper for implicits to be used by Java
def toBinaryJ[T <: Actor](a: ActorRef, format: Serializer, srlMailBox: Boolean = true): Array[Byte] =
toBinary(a, srlMailBox)(format)
def toBinaryJ[T <: Actor](
a: ActorRef,
format: Serializer,
srlMailBox: Boolean,
replicationStrategy: ReplicationStrategy): Array[Byte] =
toBinary(a, srlMailBox, replicationStrategy)(format)
private[akka] def toSerializedActorRefProtocol[T <: Actor](
actorRef: ActorRef, format: Serializer, serializeMailBox: Boolean = true): SerializedActorRefProtocol = {
actorRef: ActorRef,
format: Serializer,
serializeMailBox: Boolean,
replicationStrategy: ReplicationStrategy): SerializedActorRefProtocol = {
val lifeCycleProtocol: Option[LifeCycleProtocol] = {
actorRef.lifeCycle match {
case Permanent Some(LifeCycleProtocol.newBuilder.setLifeCycle(LifeCycleType.PERMANENT).build)
@ -52,11 +63,18 @@ object ActorSerialization {
}
}
val replicationStrategyType = replicationStrategy match {
case WriteBehind ReplicationStrategyType.WRITE_BEHIND
case WriteThrough ReplicationStrategyType.WRITE_THROUGH
case Transient ReplicationStrategyType.TRANSIENT
}
val builder = SerializedActorRefProtocol.newBuilder
.setUuid(UuidProtocol.newBuilder.setHigh(actorRef.uuid.getTime).setLow(actorRef.uuid.getClockSeqAndNode).build)
.setAddress(actorRef.address)
.setActorClassname(actorRef.actorInstance.get.getClass.getName)
.setTimeout(actorRef.timeout)
.setReplicationStrategy(replicationStrategyType)
if (serializeMailBox == true) {
if (actorRef.mailbox eq null) throw new IllegalActorStateException("Can't serialize an actor that has not been started.")
@ -115,6 +133,16 @@ object ActorSerialization {
if (protocol.hasSupervisor) Some(RemoteActorSerialization.fromProtobufToRemoteActorRef(protocol.getSupervisor, loader))
else None
import ReplicationStrategyType._
val replicationStrategy =
if (protocol.hasReplicationStrategy) {
protocol.getReplicationStrategy match {
case TRANSIENT Transient
case WRITE_THROUGH WriteThrough
case WRITE_BEHIND WriteBehind
}
} else Transient
val hotswap =
try {
format
@ -124,7 +152,7 @@ object ActorSerialization {
case e: Exception Stack[PartialFunction[Any, Unit]]()
}
val classLoader = loader.getOrElse(getClass.getClassLoader)
val classLoader = loader.getOrElse(this.getClass.getClassLoader)
val factory = () {
val actorClass = classLoader.loadClass(protocol.getActorClassname)
@ -143,7 +171,8 @@ object ActorSerialization {
lifeCycle,
supervisor,
hotswap,
factory)
factory,
replicationStrategy)
val messages = protocol.getMessagesList.toArray.toList.asInstanceOf[List[RemoteMessageProtocol]]
messages.foreach(message ar ! MessageSerializer.deserialize(message.getMessage))