diff --git a/src/core/Akka.Remote/Transport/AkkaPduCodec.cs b/src/core/Akka.Remote/Transport/AkkaPduCodec.cs index a9964c52195..14cf1b11a9f 100644 --- a/src/core/Akka.Remote/Transport/AkkaPduCodec.cs +++ b/src/core/Akka.Remote/Transport/AkkaPduCodec.cs @@ -228,14 +228,19 @@ protected AkkaPduCodec(ActorSystem system) /// TBD public virtual ByteString EncodePdu(IAkkaPdu pdu) { - ByteString finalBytes = null; - pdu.Match() - .With(a => finalBytes = ConstructAssociate(a.Info)) - .With(p => finalBytes = ConstructPayload(p.Bytes)) - .With(d => finalBytes = ConstructDisassociate(d.Reason)) - .With(h => finalBytes = ConstructHeartbeat()); - - return finalBytes; + switch (pdu) + { + case Payload p: + return ConstructPayload(p.Bytes); + case Heartbeat h: + return ConstructHeartbeat(); + case Associate a: + return ConstructAssociate(a.Info); + case Disassociate d: + return ConstructDisassociate(d.Reason); + default: + return null; // unsupported message type + } } /// @@ -376,13 +381,20 @@ public override ByteString ConstructDisassociate(DisassociateInfo reason) } } + /* + * Since there's never any ActorSystem-specific information coded directly + * into the heartbeat messages themselves (i.e. no handshake info,) there's no harm in caching in the + * same heartbeat byte buffer and re-using it. + */ + private static readonly ByteString HeartbeatPdu = ConstructControlMessagePdu(CommandType.Heartbeat); + /// - /// TBD + /// Creates a new Heartbeat message instance. /// - /// TBD + /// The Heartbeat message. public override ByteString ConstructHeartbeat() { - return ConstructControlMessagePdu(CommandType.Heartbeat); + return HeartbeatPdu; } /// @@ -533,7 +545,7 @@ private ByteString DISASSOCIATE_QUARANTINED get { return ConstructControlMessagePdu(CommandType.DisassociateQuarantined); } } - private ByteString ConstructControlMessagePdu(CommandType code, AkkaHandshakeInfo handshakeInfo = null) + private static ByteString ConstructControlMessagePdu(CommandType code, AkkaHandshakeInfo handshakeInfo = null) { var controlMessage = new AkkaControlMessage() { CommandType = code }; if (handshakeInfo != null) @@ -544,12 +556,12 @@ private ByteString ConstructControlMessagePdu(CommandType code, AkkaHandshakeInf return new AkkaProtocolMessage() { Instruction = controlMessage }.ToByteString(); } - private Address DecodeAddress(AddressData origin) + private static Address DecodeAddress(AddressData origin) { return new Address(origin.Protocol, origin.System, origin.Hostname, (int)origin.Port); } - private ActorRefData SerializeActorRef(Address defaultAddress, IActorRef actorRef) + private static ActorRefData SerializeActorRef(Address defaultAddress, IActorRef actorRef) { return new ActorRefData() { @@ -559,7 +571,7 @@ private ActorRefData SerializeActorRef(Address defaultAddress, IActorRef actorRe }; } - private AddressData SerializeAddress(Address address) + private static AddressData SerializeAddress(Address address) { if (string.IsNullOrEmpty(address.Host) || !address.Port.HasValue) throw new ArgumentException($"Address {address} could not be serialized: host or port missing");