Optimize remote serialization for the create from class case. See #1755

* Added FromClassCreator as special Function0 to be able to serialize
  class name as protobuf string
This commit is contained in:
Patrik Nordwall 2012-05-15 18:22:40 +02:00
parent 793af8b4ec
commit 31ace9e83f
5 changed files with 278 additions and 160 deletions

View file

@ -127,7 +127,7 @@ case class Props(
* Java API.
*/
def this(actorClass: Class[_ <: Actor]) = this(
creator = () actorClass.newInstance,
creator = FromClassCreator(actorClass),
dispatcher = Dispatchers.DefaultDispatcherId,
routerConfig = Props.defaultRoutedProps)
@ -150,7 +150,7 @@ case class Props(
*
* Java API.
*/
def withCreator(c: Class[_ <: Actor]): Props = copy(creator = () c.newInstance)
def withCreator(c: Class[_ <: Actor]): Props = copy(creator = FromClassCreator(c))
/**
* Returns a new Props with the specified dispatcher set.
@ -166,4 +166,13 @@ case class Props(
* Returns a new Props with the specified deployment configuration.
*/
def withDeploy(d: Deploy): Props = copy(deploy = d)
}
/**
* Used when creating an Actor from a class. Special Function0 to be
* able to optimize serialization.
*/
private[akka] case class FromClassCreator(clazz: Class[_ <: Actor]) extends Function0[Actor] {
def apply(): Actor = clazz.newInstance
}

View file

@ -5035,20 +5035,24 @@ public final class RemoteProtocol {
public interface PropsProtocolOrBuilder
extends com.google.protobuf.MessageOrBuilder {
// required bytes creator = 1;
boolean hasCreator();
com.google.protobuf.ByteString getCreator();
// required string dispatcher = 2;
// required string dispatcher = 1;
boolean hasDispatcher();
String getDispatcher();
// required .DeployProtocol deploy = 3;
// required .DeployProtocol deploy = 2;
boolean hasDeploy();
akka.remote.RemoteProtocol.DeployProtocol getDeploy();
akka.remote.RemoteProtocol.DeployProtocolOrBuilder getDeployOrBuilder();
// optional bytes routerConfig = 4;
// optional string fromClassCreator = 3;
boolean hasFromClassCreator();
String getFromClassCreator();
// optional bytes creator = 4;
boolean hasCreator();
com.google.protobuf.ByteString getCreator();
// optional bytes routerConfig = 5;
boolean hasRouterConfig();
com.google.protobuf.ByteString getRouterConfig();
}
@ -5081,21 +5085,11 @@ public final class RemoteProtocol {
}
private int bitField0_;
// required bytes creator = 1;
public static final int CREATOR_FIELD_NUMBER = 1;
private com.google.protobuf.ByteString creator_;
public boolean hasCreator() {
return ((bitField0_ & 0x00000001) == 0x00000001);
}
public com.google.protobuf.ByteString getCreator() {
return creator_;
}
// required string dispatcher = 2;
public static final int DISPATCHER_FIELD_NUMBER = 2;
// required string dispatcher = 1;
public static final int DISPATCHER_FIELD_NUMBER = 1;
private java.lang.Object dispatcher_;
public boolean hasDispatcher() {
return ((bitField0_ & 0x00000002) == 0x00000002);
return ((bitField0_ & 0x00000001) == 0x00000001);
}
public String getDispatcher() {
java.lang.Object ref = dispatcher_;
@ -5123,11 +5117,11 @@ public final class RemoteProtocol {
}
}
// required .DeployProtocol deploy = 3;
public static final int DEPLOY_FIELD_NUMBER = 3;
// required .DeployProtocol deploy = 2;
public static final int DEPLOY_FIELD_NUMBER = 2;
private akka.remote.RemoteProtocol.DeployProtocol deploy_;
public boolean hasDeploy() {
return ((bitField0_ & 0x00000004) == 0x00000004);
return ((bitField0_ & 0x00000002) == 0x00000002);
}
public akka.remote.RemoteProtocol.DeployProtocol getDeploy() {
return deploy_;
@ -5136,20 +5130,63 @@ public final class RemoteProtocol {
return deploy_;
}
// optional bytes routerConfig = 4;
public static final int ROUTERCONFIG_FIELD_NUMBER = 4;
// optional string fromClassCreator = 3;
public static final int FROMCLASSCREATOR_FIELD_NUMBER = 3;
private java.lang.Object fromClassCreator_;
public boolean hasFromClassCreator() {
return ((bitField0_ & 0x00000004) == 0x00000004);
}
public String getFromClassCreator() {
java.lang.Object ref = fromClassCreator_;
if (ref instanceof String) {
return (String) ref;
} else {
com.google.protobuf.ByteString bs =
(com.google.protobuf.ByteString) ref;
String s = bs.toStringUtf8();
if (com.google.protobuf.Internal.isValidUtf8(bs)) {
fromClassCreator_ = s;
}
return s;
}
}
private com.google.protobuf.ByteString getFromClassCreatorBytes() {
java.lang.Object ref = fromClassCreator_;
if (ref instanceof String) {
com.google.protobuf.ByteString b =
com.google.protobuf.ByteString.copyFromUtf8((String) ref);
fromClassCreator_ = b;
return b;
} else {
return (com.google.protobuf.ByteString) ref;
}
}
// optional bytes creator = 4;
public static final int CREATOR_FIELD_NUMBER = 4;
private com.google.protobuf.ByteString creator_;
public boolean hasCreator() {
return ((bitField0_ & 0x00000008) == 0x00000008);
}
public com.google.protobuf.ByteString getCreator() {
return creator_;
}
// optional bytes routerConfig = 5;
public static final int ROUTERCONFIG_FIELD_NUMBER = 5;
private com.google.protobuf.ByteString routerConfig_;
public boolean hasRouterConfig() {
return ((bitField0_ & 0x00000008) == 0x00000008);
return ((bitField0_ & 0x00000010) == 0x00000010);
}
public com.google.protobuf.ByteString getRouterConfig() {
return routerConfig_;
}
private void initFields() {
creator_ = com.google.protobuf.ByteString.EMPTY;
dispatcher_ = "";
deploy_ = akka.remote.RemoteProtocol.DeployProtocol.getDefaultInstance();
fromClassCreator_ = "";
creator_ = com.google.protobuf.ByteString.EMPTY;
routerConfig_ = com.google.protobuf.ByteString.EMPTY;
}
private byte memoizedIsInitialized = -1;
@ -5157,10 +5194,6 @@ public final class RemoteProtocol {
byte isInitialized = memoizedIsInitialized;
if (isInitialized != -1) return isInitialized == 1;
if (!hasCreator()) {
memoizedIsInitialized = 0;
return false;
}
if (!hasDispatcher()) {
memoizedIsInitialized = 0;
return false;
@ -5181,16 +5214,19 @@ public final class RemoteProtocol {
throws java.io.IOException {
getSerializedSize();
if (((bitField0_ & 0x00000001) == 0x00000001)) {
output.writeBytes(1, creator_);
output.writeBytes(1, getDispatcherBytes());
}
if (((bitField0_ & 0x00000002) == 0x00000002)) {
output.writeBytes(2, getDispatcherBytes());
output.writeMessage(2, deploy_);
}
if (((bitField0_ & 0x00000004) == 0x00000004)) {
output.writeMessage(3, deploy_);
output.writeBytes(3, getFromClassCreatorBytes());
}
if (((bitField0_ & 0x00000008) == 0x00000008)) {
output.writeBytes(4, routerConfig_);
output.writeBytes(4, creator_);
}
if (((bitField0_ & 0x00000010) == 0x00000010)) {
output.writeBytes(5, routerConfig_);
}
getUnknownFields().writeTo(output);
}
@ -5203,19 +5239,23 @@ public final class RemoteProtocol {
size = 0;
if (((bitField0_ & 0x00000001) == 0x00000001)) {
size += com.google.protobuf.CodedOutputStream
.computeBytesSize(1, creator_);
.computeBytesSize(1, getDispatcherBytes());
}
if (((bitField0_ & 0x00000002) == 0x00000002)) {
size += com.google.protobuf.CodedOutputStream
.computeBytesSize(2, getDispatcherBytes());
.computeMessageSize(2, deploy_);
}
if (((bitField0_ & 0x00000004) == 0x00000004)) {
size += com.google.protobuf.CodedOutputStream
.computeMessageSize(3, deploy_);
.computeBytesSize(3, getFromClassCreatorBytes());
}
if (((bitField0_ & 0x00000008) == 0x00000008)) {
size += com.google.protobuf.CodedOutputStream
.computeBytesSize(4, routerConfig_);
.computeBytesSize(4, creator_);
}
if (((bitField0_ & 0x00000010) == 0x00000010)) {
size += com.google.protobuf.CodedOutputStream
.computeBytesSize(5, routerConfig_);
}
size += getUnknownFields().getSerializedSize();
memoizedSerializedSize = size;
@ -5342,18 +5382,20 @@ public final class RemoteProtocol {
public Builder clear() {
super.clear();
creator_ = com.google.protobuf.ByteString.EMPTY;
bitField0_ = (bitField0_ & ~0x00000001);
dispatcher_ = "";
bitField0_ = (bitField0_ & ~0x00000002);
bitField0_ = (bitField0_ & ~0x00000001);
if (deployBuilder_ == null) {
deploy_ = akka.remote.RemoteProtocol.DeployProtocol.getDefaultInstance();
} else {
deployBuilder_.clear();
}
bitField0_ = (bitField0_ & ~0x00000002);
fromClassCreator_ = "";
bitField0_ = (bitField0_ & ~0x00000004);
routerConfig_ = com.google.protobuf.ByteString.EMPTY;
creator_ = com.google.protobuf.ByteString.EMPTY;
bitField0_ = (bitField0_ & ~0x00000008);
routerConfig_ = com.google.protobuf.ByteString.EMPTY;
bitField0_ = (bitField0_ & ~0x00000010);
return this;
}
@ -5395,22 +5437,26 @@ public final class RemoteProtocol {
if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
to_bitField0_ |= 0x00000001;
}
result.creator_ = creator_;
result.dispatcher_ = dispatcher_;
if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
to_bitField0_ |= 0x00000002;
}
result.dispatcher_ = dispatcher_;
if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
to_bitField0_ |= 0x00000004;
}
if (deployBuilder_ == null) {
result.deploy_ = deploy_;
} else {
result.deploy_ = deployBuilder_.build();
}
if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
to_bitField0_ |= 0x00000004;
}
result.fromClassCreator_ = fromClassCreator_;
if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
to_bitField0_ |= 0x00000008;
}
result.creator_ = creator_;
if (((from_bitField0_ & 0x00000010) == 0x00000010)) {
to_bitField0_ |= 0x00000010;
}
result.routerConfig_ = routerConfig_;
result.bitField0_ = to_bitField0_;
onBuilt();
@ -5428,15 +5474,18 @@ public final class RemoteProtocol {
public Builder mergeFrom(akka.remote.RemoteProtocol.PropsProtocol other) {
if (other == akka.remote.RemoteProtocol.PropsProtocol.getDefaultInstance()) return this;
if (other.hasCreator()) {
setCreator(other.getCreator());
}
if (other.hasDispatcher()) {
setDispatcher(other.getDispatcher());
}
if (other.hasDeploy()) {
mergeDeploy(other.getDeploy());
}
if (other.hasFromClassCreator()) {
setFromClassCreator(other.getFromClassCreator());
}
if (other.hasCreator()) {
setCreator(other.getCreator());
}
if (other.hasRouterConfig()) {
setRouterConfig(other.getRouterConfig());
}
@ -5445,10 +5494,6 @@ public final class RemoteProtocol {
}
public final boolean isInitialized() {
if (!hasCreator()) {
return false;
}
if (!hasDispatcher()) {
return false;
@ -5489,15 +5534,10 @@ public final class RemoteProtocol {
}
case 10: {
bitField0_ |= 0x00000001;
creator_ = input.readBytes();
break;
}
case 18: {
bitField0_ |= 0x00000002;
dispatcher_ = input.readBytes();
break;
}
case 26: {
case 18: {
akka.remote.RemoteProtocol.DeployProtocol.Builder subBuilder = akka.remote.RemoteProtocol.DeployProtocol.newBuilder();
if (hasDeploy()) {
subBuilder.mergeFrom(getDeploy());
@ -5506,8 +5546,18 @@ public final class RemoteProtocol {
setDeploy(subBuilder.buildPartial());
break;
}
case 26: {
bitField0_ |= 0x00000004;
fromClassCreator_ = input.readBytes();
break;
}
case 34: {
bitField0_ |= 0x00000008;
creator_ = input.readBytes();
break;
}
case 42: {
bitField0_ |= 0x00000010;
routerConfig_ = input.readBytes();
break;
}
@ -5517,34 +5567,10 @@ public final class RemoteProtocol {
private int bitField0_;
// required bytes creator = 1;
private com.google.protobuf.ByteString creator_ = com.google.protobuf.ByteString.EMPTY;
public boolean hasCreator() {
return ((bitField0_ & 0x00000001) == 0x00000001);
}
public com.google.protobuf.ByteString getCreator() {
return creator_;
}
public Builder setCreator(com.google.protobuf.ByteString value) {
if (value == null) {
throw new NullPointerException();
}
bitField0_ |= 0x00000001;
creator_ = value;
onChanged();
return this;
}
public Builder clearCreator() {
bitField0_ = (bitField0_ & ~0x00000001);
creator_ = getDefaultInstance().getCreator();
onChanged();
return this;
}
// required string dispatcher = 2;
// required string dispatcher = 1;
private java.lang.Object dispatcher_ = "";
public boolean hasDispatcher() {
return ((bitField0_ & 0x00000002) == 0x00000002);
return ((bitField0_ & 0x00000001) == 0x00000001);
}
public String getDispatcher() {
java.lang.Object ref = dispatcher_;
@ -5560,29 +5586,29 @@ public final class RemoteProtocol {
if (value == null) {
throw new NullPointerException();
}
bitField0_ |= 0x00000002;
bitField0_ |= 0x00000001;
dispatcher_ = value;
onChanged();
return this;
}
public Builder clearDispatcher() {
bitField0_ = (bitField0_ & ~0x00000002);
bitField0_ = (bitField0_ & ~0x00000001);
dispatcher_ = getDefaultInstance().getDispatcher();
onChanged();
return this;
}
void setDispatcher(com.google.protobuf.ByteString value) {
bitField0_ |= 0x00000002;
bitField0_ |= 0x00000001;
dispatcher_ = value;
onChanged();
}
// required .DeployProtocol deploy = 3;
// required .DeployProtocol deploy = 2;
private akka.remote.RemoteProtocol.DeployProtocol deploy_ = akka.remote.RemoteProtocol.DeployProtocol.getDefaultInstance();
private com.google.protobuf.SingleFieldBuilder<
akka.remote.RemoteProtocol.DeployProtocol, akka.remote.RemoteProtocol.DeployProtocol.Builder, akka.remote.RemoteProtocol.DeployProtocolOrBuilder> deployBuilder_;
public boolean hasDeploy() {
return ((bitField0_ & 0x00000004) == 0x00000004);
return ((bitField0_ & 0x00000002) == 0x00000002);
}
public akka.remote.RemoteProtocol.DeployProtocol getDeploy() {
if (deployBuilder_ == null) {
@ -5601,7 +5627,7 @@ public final class RemoteProtocol {
} else {
deployBuilder_.setMessage(value);
}
bitField0_ |= 0x00000004;
bitField0_ |= 0x00000002;
return this;
}
public Builder setDeploy(
@ -5612,12 +5638,12 @@ public final class RemoteProtocol {
} else {
deployBuilder_.setMessage(builderForValue.build());
}
bitField0_ |= 0x00000004;
bitField0_ |= 0x00000002;
return this;
}
public Builder mergeDeploy(akka.remote.RemoteProtocol.DeployProtocol value) {
if (deployBuilder_ == null) {
if (((bitField0_ & 0x00000004) == 0x00000004) &&
if (((bitField0_ & 0x00000002) == 0x00000002) &&
deploy_ != akka.remote.RemoteProtocol.DeployProtocol.getDefaultInstance()) {
deploy_ =
akka.remote.RemoteProtocol.DeployProtocol.newBuilder(deploy_).mergeFrom(value).buildPartial();
@ -5628,7 +5654,7 @@ public final class RemoteProtocol {
} else {
deployBuilder_.mergeFrom(value);
}
bitField0_ |= 0x00000004;
bitField0_ |= 0x00000002;
return this;
}
public Builder clearDeploy() {
@ -5638,11 +5664,11 @@ public final class RemoteProtocol {
} else {
deployBuilder_.clear();
}
bitField0_ = (bitField0_ & ~0x00000004);
bitField0_ = (bitField0_ & ~0x00000002);
return this;
}
public akka.remote.RemoteProtocol.DeployProtocol.Builder getDeployBuilder() {
bitField0_ |= 0x00000004;
bitField0_ |= 0x00000002;
onChanged();
return getDeployFieldBuilder().getBuilder();
}
@ -5667,10 +5693,70 @@ public final class RemoteProtocol {
return deployBuilder_;
}
// optional bytes routerConfig = 4;
// optional string fromClassCreator = 3;
private java.lang.Object fromClassCreator_ = "";
public boolean hasFromClassCreator() {
return ((bitField0_ & 0x00000004) == 0x00000004);
}
public String getFromClassCreator() {
java.lang.Object ref = fromClassCreator_;
if (!(ref instanceof String)) {
String s = ((com.google.protobuf.ByteString) ref).toStringUtf8();
fromClassCreator_ = s;
return s;
} else {
return (String) ref;
}
}
public Builder setFromClassCreator(String value) {
if (value == null) {
throw new NullPointerException();
}
bitField0_ |= 0x00000004;
fromClassCreator_ = value;
onChanged();
return this;
}
public Builder clearFromClassCreator() {
bitField0_ = (bitField0_ & ~0x00000004);
fromClassCreator_ = getDefaultInstance().getFromClassCreator();
onChanged();
return this;
}
void setFromClassCreator(com.google.protobuf.ByteString value) {
bitField0_ |= 0x00000004;
fromClassCreator_ = value;
onChanged();
}
// optional bytes creator = 4;
private com.google.protobuf.ByteString creator_ = com.google.protobuf.ByteString.EMPTY;
public boolean hasCreator() {
return ((bitField0_ & 0x00000008) == 0x00000008);
}
public com.google.protobuf.ByteString getCreator() {
return creator_;
}
public Builder setCreator(com.google.protobuf.ByteString value) {
if (value == null) {
throw new NullPointerException();
}
bitField0_ |= 0x00000008;
creator_ = value;
onChanged();
return this;
}
public Builder clearCreator() {
bitField0_ = (bitField0_ & ~0x00000008);
creator_ = getDefaultInstance().getCreator();
onChanged();
return this;
}
// optional bytes routerConfig = 5;
private com.google.protobuf.ByteString routerConfig_ = com.google.protobuf.ByteString.EMPTY;
public boolean hasRouterConfig() {
return ((bitField0_ & 0x00000008) == 0x00000008);
return ((bitField0_ & 0x00000010) == 0x00000010);
}
public com.google.protobuf.ByteString getRouterConfig() {
return routerConfig_;
@ -5679,13 +5765,13 @@ public final class RemoteProtocol {
if (value == null) {
throw new NullPointerException();
}
bitField0_ |= 0x00000008;
bitField0_ |= 0x00000010;
routerConfig_ = value;
onChanged();
return this;
}
public Builder clearRouterConfig() {
bitField0_ = (bitField0_ & ~0x00000008);
bitField0_ = (bitField0_ & ~0x00000010);
routerConfig_ = getDefaultInstance().getRouterConfig();
onChanged();
return this;
@ -6947,17 +7033,17 @@ public final class RemoteProtocol {
"\014\n\004port\030\003 \002(\r\"\216\001\n\027DaemonMsgCreateProtoco" +
"l\022\035\n\005props\030\001 \002(\0132\016.PropsProtocol\022\037\n\006depl" +
"oy\030\002 \002(\0132\017.DeployProtocol\022\014\n\004path\030\003 \002(\t\022" +
"%\n\nsupervisor\030\004 \002(\0132\021.ActorRefProtocol\"k",
"\n\rPropsProtocol\022\017\n\007creator\030\001 \002(\014\022\022\n\ndisp" +
"atcher\030\002 \002(\t\022\037\n\006deploy\030\003 \002(\0132\017.DeployPro" +
"tocol\022\024\n\014routerConfig\030\004 \001(\014\"S\n\016DeployPro" +
"tocol\022\014\n\004path\030\001 \002(\t\022\016\n\006config\030\002 \001(\014\022\024\n\014r" +
"outerConfig\030\003 \001(\014\022\r\n\005scope\030\004 \001(\014\"`\n\026Daem" +
"onMsgWatchProtocol\022\"\n\007watcher\030\001 \002(\0132\021.Ac" +
"torRefProtocol\022\"\n\007watched\030\002 \002(\0132\021.ActorR" +
"efProtocol*7\n\013CommandType\022\013\n\007CONNECT\020\001\022\014" +
"\n\010SHUTDOWN\020\002\022\r\n\tHEARTBEAT\020\003B\017\n\013akka.remo" +
"teH\001"
"%\n\nsupervisor\030\004 \002(\0132\021.ActorRefProtocol\"\205",
"\001\n\rPropsProtocol\022\022\n\ndispatcher\030\001 \002(\t\022\037\n\006" +
"deploy\030\002 \002(\0132\017.DeployProtocol\022\030\n\020fromCla" +
"ssCreator\030\003 \001(\t\022\017\n\007creator\030\004 \001(\014\022\024\n\014rout" +
"erConfig\030\005 \001(\014\"S\n\016DeployProtocol\022\014\n\004path" +
"\030\001 \002(\t\022\016\n\006config\030\002 \001(\014\022\024\n\014routerConfig\030\003" +
" \001(\014\022\r\n\005scope\030\004 \001(\014\"`\n\026DaemonMsgWatchPro" +
"tocol\022\"\n\007watcher\030\001 \002(\0132\021.ActorRefProtoco" +
"l\022\"\n\007watched\030\002 \002(\0132\021.ActorRefProtocol*7\n" +
"\013CommandType\022\013\n\007CONNECT\020\001\022\014\n\010SHUTDOWN\020\002\022" +
"\r\n\tHEARTBEAT\020\003B\017\n\013akka.remoteH\001"
};
com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
@ -7033,7 +7119,7 @@ public final class RemoteProtocol {
internal_static_PropsProtocol_fieldAccessorTable = new
com.google.protobuf.GeneratedMessage.FieldAccessorTable(
internal_static_PropsProtocol_descriptor,
new java.lang.String[] { "Creator", "Dispatcher", "Deploy", "RouterConfig", },
new java.lang.String[] { "Dispatcher", "Deploy", "FromClassCreator", "Creator", "RouterConfig", },
akka.remote.RemoteProtocol.PropsProtocol.class,
akka.remote.RemoteProtocol.PropsProtocol.Builder.class);
internal_static_DeployProtocol_descriptor =

View file

@ -92,10 +92,11 @@ message DaemonMsgCreateProtocol {
* Serialization of akka.actor.Props
*/
message PropsProtocol {
required bytes creator = 1;
required string dispatcher = 2;
required DeployProtocol deploy = 3;
optional bytes routerConfig = 4;
required string dispatcher = 1;
required DeployProtocol deploy = 2;
optional string fromClassCreator = 3;
optional bytes creator = 4;
optional bytes routerConfig = 5;
}
/**

View file

@ -5,11 +5,9 @@
package akka.serialization
import java.io.Serializable
import com.google.protobuf.ByteString
import com.typesafe.config.Config
import com.typesafe.config.ConfigFactory
import akka.actor.Actor
import akka.actor.ActorRef
import akka.actor.Deploy
@ -24,12 +22,14 @@ import akka.remote.RemoteProtocol.DeployProtocol
import akka.remote.RemoteProtocol.PropsProtocol
import akka.routing.NoRouter
import akka.routing.RouterConfig
import akka.actor.FromClassCreator
/**
* Serializes akka's internal DaemonMsgCreate using protobuf
* for the core structure of DaemonMsgCreate, Props and Deploy.
* Serialization of contained RouterConfig, Config, Scope, and creator (scala.Function0)
* is done with configured serializer for those classes, by default java.io.Serializable.
* Serialization of contained RouterConfig, Config, and Scope
* is done with configured serializer for those classes, by
* default java.io.Serializable.
*/
class DaemonMsgCreateSerializer(val system: ExtendedActorSystem) extends Serializer {
import ProtobufSerializer.serializeActorRef
@ -55,9 +55,12 @@ class DaemonMsgCreateSerializer(val system: ExtendedActorSystem) extends Seriali
def propsProto = {
val builder = PropsProtocol.newBuilder.
setCreator(serialize(props.creator)).
setDispatcher(props.dispatcher).
setDeploy(deployProto(props.deploy))
props.creator match {
case FromClassCreator(clazz) builder.setFromClassCreator(clazz.getName)
case creator builder.setCreator(serialize(creator))
}
if (props.routerConfig != NoRouter)
builder.setRouterConfig(serialize(props.routerConfig))
builder.build
@ -92,11 +95,22 @@ class DaemonMsgCreateSerializer(val system: ExtendedActorSystem) extends Seriali
}
def props = {
val creator =
if (proto.getProps.hasFromClassCreator) {
system.dynamicAccess.getClassFor(proto.getProps.getFromClassCreator) match {
case Right(clazz) FromClassCreator(clazz)
case Left(e) throw e
}
} else {
deserialize(proto.getProps.getCreator, classOf[() Actor])
}
val routerConfig =
if (proto.getProps.hasRouterConfig) deserialize(proto.getProps.getRouterConfig, classOf[RouterConfig])
else NoRouter
Props(
creator = deserialize(proto.getProps.getCreator, classOf[() Actor]),
creator = creator,
dispatcher = proto.getProps.getDispatcher,
routerConfig = routerConfig,
deploy = deploy(proto.getProps.getDeploy))
@ -124,7 +138,6 @@ class DaemonMsgCreateSerializer(val system: ExtendedActorSystem) extends Seriali
case Left(e)
// Fallback to the java serializer, because some interfaces don't implement java.io.Serializable,
// but the impl instance does. This could be optimized by adding java serializers in reference.conf:
// scala.Function0 (the creator)
// com.typesafe.config.Config
// akka.routing.RouterConfig
// akka.actor.Scope

View file

@ -17,6 +17,7 @@ import akka.remote.RemoteScope
import akka.routing.RoundRobinRouter
import akka.routing.FromConfig
import akka.util.duration._
import akka.actor.FromClassCreator
object DaemonMsgCreateSerializerSpec {
class MyActor extends Actor {
@ -39,45 +40,51 @@ class DaemonMsgCreateSerializerSpec extends AkkaSpec {
ser.serializerFor(classOf[DaemonMsgCreate]).getClass must be(classOf[DaemonMsgCreateSerializer])
}
"serialize and de-serialize simple DaemonMsgCreate" in {
val msg = DaemonMsgCreate(
props = Props[MyActor],
deploy = Deploy(),
path = "foo",
supervisor = supervisor)
val bytes = ser.serialize(msg) match {
case Left(exception) fail(exception)
case Right(bytes) bytes
"serialize and de-serialize DaemonMsgCreate with FromClassCreator" in {
verifySerialization {
DaemonMsgCreate(
props = Props[MyActor],
deploy = Deploy(),
path = "foo",
supervisor = supervisor)
}
ser.deserialize(bytes.asInstanceOf[Array[Byte]], classOf[DaemonMsgCreate]) match {
case Left(exception) fail(exception)
case Right(m: DaemonMsgCreate) assertDaemonMsgCreate(msg, m)
}
"serialize and de-serialize DaemonMsgCreate with function creator" in {
verifySerialization {
DaemonMsgCreate(
props = Props().withCreator(new MyActor),
deploy = Deploy(),
path = "foo",
supervisor = supervisor)
}
}
"serialize and de-serialize DaemonMsgCreate with Deploy and RouterConfig" in {
// Duration.Inf doesn't equal Duration.Inf, so we use another for test
val supervisorStrategy = OneForOneStrategy(3, 10 seconds) {
case _ SupervisorStrategy.Escalate
verifySerialization {
// Duration.Inf doesn't equal Duration.Inf, so we use another for test
val supervisorStrategy = OneForOneStrategy(3, 10 seconds) {
case _ SupervisorStrategy.Escalate
}
val deploy1 = Deploy(
path = "path1",
config = ConfigFactory.parseString("a=1"),
routerConfig = RoundRobinRouter(nrOfInstances = 5, supervisorStrategy = supervisorStrategy),
scope = RemoteScope(Address("akka", "Test", "host1", 1921)))
val deploy2 = Deploy(
path = "path2",
config = ConfigFactory.parseString("a=2"),
routerConfig = FromConfig,
scope = RemoteScope(Address("akka", "Test", "host2", 1922)))
DaemonMsgCreate(
props = Props[MyActor].withDispatcher("my-disp").withDeploy(deploy1),
deploy = deploy2,
path = "foo",
supervisor = supervisor)
}
val deploy1 = Deploy(
path = "path1",
config = ConfigFactory.parseString("a=1"),
routerConfig = RoundRobinRouter(nrOfInstances = 5, supervisorStrategy = supervisorStrategy),
scope = RemoteScope(Address("akka", "Test", "host1", 1921)))
val deploy2 = Deploy(
path = "path2",
config = ConfigFactory.parseString("a=2"),
routerConfig = FromConfig,
scope = RemoteScope(Address("akka", "Test", "host2", 1922)))
val msg = DaemonMsgCreate(
props = Props[MyActor].withDispatcher("my-disp").withDeploy(deploy1),
deploy = deploy2,
path = "foo",
supervisor = supervisor)
}
def verifySerialization(msg: DaemonMsgCreate): Unit = {
val bytes = ser.serialize(msg) match {
case Left(exception) fail(exception)
case Right(bytes) bytes
@ -89,7 +96,9 @@ class DaemonMsgCreateSerializerSpec extends AkkaSpec {
}
def assertDaemonMsgCreate(expected: DaemonMsgCreate, got: DaemonMsgCreate): Unit = {
// can't compare props.creator
// can't compare props.creator when function
if (expected.props.creator.isInstanceOf[FromClassCreator])
assert(got.props.creator === expected.props.creator)
assert(got.props.dispatcher === expected.props.dispatcher)
assert(got.props.dispatcher === expected.props.dispatcher)
assert(got.props.routerConfig === expected.props.routerConfig)