public void ReceiveBuffer_must_enqueue_message_in_buffer_if_needed_return_the_list_of_deliverable_messages_and_acks() { var b0 = new AckedReceiveBuffer <Sequenced>(); var msg0 = Msg(0); var msg1 = Msg(1); var msg2 = Msg(2); var msg3 = Msg(3); var msg4 = Msg(4); var msg5 = Msg(5); var d1 = b0.Receive(msg1).ExtractDeliverable(); Assert.True(d1.Deliverables.Count == 0); Assert.Equal(new SeqNo(1), d1.Ack.CumulativeAck); Assert.True(d1.Ack.Nacks.SequenceEqual(new[] { new SeqNo(0) })); var b1 = d1.Buffer; var d2 = b1.Receive(msg0).ExtractDeliverable(); Assert.True(d2.Deliverables.SequenceEqual(new[] { msg0, msg1 })); Assert.Equal(new SeqNo(1), d2.Ack.CumulativeAck); var b3 = d2.Buffer; var d3 = b3.Receive(msg4).ExtractDeliverable(); Assert.True(d3.Deliverables.Count == 0); Assert.Equal(new SeqNo(4), d3.Ack.CumulativeAck); Assert.True(d3.Ack.Nacks.SequenceEqual(new[] { new SeqNo(2), new SeqNo(3) })); var b4 = d3.Buffer; var d4 = b4.Receive(msg2).ExtractDeliverable(); Assert.True(d4.Deliverables.SequenceEqual(new[] { msg2 })); Assert.Equal(new SeqNo(4), d4.Ack.CumulativeAck); Assert.True(d4.Ack.Nacks.SequenceEqual(new[] { new SeqNo(3) })); var b5 = d4.Buffer; var d5 = b5.Receive(msg5).ExtractDeliverable(); Assert.True(d5.Deliverables.Count == 0); Assert.Equal(new SeqNo(5), d5.Ack.CumulativeAck); Assert.True(d5.Ack.Nacks.SequenceEqual(new[] { new SeqNo(3) })); var b6 = d5.Buffer; var d6 = b6.Receive(msg3).ExtractDeliverable(); Assert.True(d6.Deliverables.SequenceEqual(new[] { msg3, msg4, msg5 })); Assert.Equal(new SeqNo(5), d6.Ack.CumulativeAck); }
public void ReceiveBuffer_must_handle_duplicate_arrivals_correctly() { var buf = new AckedReceiveBuffer <Sequenced>(); var msg0 = Msg(0); var msg1 = Msg(1); var msg2 = Msg(2); var buf2 = buf.Receive(msg0).Receive(msg1).Receive(msg2).ExtractDeliverable().Buffer; var buf3 = buf2.Receive(msg0).Receive(msg1).Receive(msg2); var d = buf3.ExtractDeliverable(); Assert.True(d.Deliverables.Count == 0); Assert.Equal(new SeqNo(2), d.Ack.CumulativeAck); }
public void ReceiveBuffer_must_be_able_to_correctly_merge_with_another_receive_buffer() { var buf1 = new AckedReceiveBuffer <Sequenced>(); var buf2 = new AckedReceiveBuffer <Sequenced>(); var msg0 = Msg(0); var msg1a = Msg(1); var msg1b = Msg(1); var msg2 = Msg(2); var msg3 = Msg(3); var buf = buf1.Receive(msg1a).Receive(msg2).MergeFrom(buf2.Receive(msg1b).Receive(msg3)); var d = buf.Receive(msg0).ExtractDeliverable(); Assert.True(d.Deliverables.SequenceEqual(new [] { msg0, msg1a, msg2, msg3 })); Assert.Equal(new SeqNo(3), d.Ack.CumulativeAck); }
private void DeliverAndAck() { var deliverable = _ackedReceiveBuffer.ExtractDeliverable; _ackedReceiveBuffer = deliverable.Buffer; // Notify writer that some messages can be acked Context.Parent.Tell(new EndpointWriter.OutboundAck(deliverable.Ack)); deliverable.Deliverables.ForEach(msg => _msgDispatch.Dispatch(msg.Recipient, msg.RecipientAddress, msg.SerializedMessage, msg.SenderOptional)); }
protected override void OnReceive(object message) { if (message is Disassociated) { HandleDisassociated((message as Disassociated).Info); } else if (message is InboundPayload) { var payload = message as InboundPayload; var ackAndMessage = TryDecodeMessageAndAck(payload.Payload); if (ackAndMessage.AckOption != null && _reliableDeliverySupervisor != null) _reliableDeliverySupervisor.Tell(ackAndMessage.AckOption); if (ackAndMessage.MessageOption != null) { if (ackAndMessage.MessageOption.ReliableDeliveryEnabled) { _ackedReceiveBuffer = _ackedReceiveBuffer.Receive(ackAndMessage.MessageOption); DeliverAndAck(); } else { _msgDispatch.Dispatch(ackAndMessage.MessageOption.Recipient, ackAndMessage.MessageOption.RecipientAddress, ackAndMessage.MessageOption.SerializedMessage, ackAndMessage.MessageOption.SenderOptional); } } } else if (message is EndpointWriter.StopReading) { var stop = message as EndpointWriter.StopReading; SaveState(); Context.Become(NotReading); stop.ReplyTo.Tell(new EndpointWriter.StoppedReading(stop.Writer)); } else { Unhandled(message); } }
protected override void PreStart() { EndpointManager.ResendState resendState; if (_receiveBuffers.TryGetValue(new EndpointManager.Link(LocalAddress, RemoteAddress), out resendState)) { _ackedReceiveBuffer = resendState.Buffer; DeliverAndAck(); } }
public ResendState(int uid, AckedReceiveBuffer<Message> buffer) { Buffer = buffer; Uid = uid; }
public void SendBuffer_and_ReceiveBuffer_must_correctly_cooperate_with_each_other() { var msgCount = 1000; var deliveryProbability = 0.5D; var referenceList = Enumerable.Range(0, msgCount).Select(x => Msg(x)).ToList(); var toSend = referenceList; var received = new List <Sequenced>(); var sndBuf = new AckedSendBuffer <Sequenced>(10); var rcvBuf = new AckedReceiveBuffer <Sequenced>(); var log = new List <string>(); var lastAck = new Ack(new SeqNo(-1)); Action <string> dbLog = log.Add; Action <int, double> senderSteps = (steps, p) => { var resends = new List <Sequenced>(sndBuf.Nacked.Concat(sndBuf.NonAcked).Take(steps)); var sends = new List <Sequenced>(); if (steps - resends.Count > 0) { var tmp = toSend.Take(steps - resends.Count).ToList(); toSend = toSend.Drop(steps - resends.Count).ToList(); sends = tmp; } foreach (var msg in resends.Concat(sends)) { if (sends.Contains(msg)) { sndBuf = sndBuf.Buffer(msg); } if (Happened(p)) { var del = rcvBuf.Receive(msg).ExtractDeliverable(); rcvBuf = del.Buffer; dbLog(string.Format("{0} -- {1} --> {2}", sndBuf, msg, rcvBuf)); lastAck = del.Ack; received.AddRange(del.Deliverables); dbLog(string.Format("R: {0}", string.Join(",", received.Select(x => x.ToString())))); } else { dbLog(string.Format("{0} -- {1} --X {2}", sndBuf, msg, rcvBuf)); } } }; Action <double> receiverStep = (p) => { if (Happened(p)) { sndBuf = sndBuf.Acknowledge(lastAck); dbLog(string.Format("{0} <-- {1} -- {2}", sndBuf, lastAck, rcvBuf)); } else { dbLog(string.Format("{0} X-- {1} -- {2}", sndBuf, lastAck, rcvBuf)); } }; //Dropping phase global::System.Diagnostics.Debug.WriteLine("Starting unreliable delivery for {0} messages, with delivery probably P = {1}", msgCount, deliveryProbability); var nextSteps = msgCount * 2; while (nextSteps > 0) { var s = Geom(0.3, limit: 5); senderSteps(s, deliveryProbability); receiverStep(deliveryProbability); nextSteps--; } global::System.Diagnostics.Debug.WriteLine("Successfully delivered {0} messages from {1}", received.Count, msgCount); global::System.Diagnostics.Debug.WriteLine("Entering reliable phase"); //Finalizing phase for (var i = 1; i <= msgCount; i++) { senderSteps(1, 1.0); receiverStep(1.0); } if (!received.SequenceEqual(referenceList)) { global::System.Diagnostics.Debug.WriteLine(string.Join(Environment.NewLine, log)); global::System.Diagnostics.Debug.WriteLine("Received: "); global::System.Diagnostics.Debug.WriteLine(string.Join(Environment.NewLine, received.Select(x => x.ToString()))); Assert.True(false, "Not all messages were received"); } global::System.Diagnostics.Debug.WriteLine("All messages have been successfully delivered"); }
public void SendBuffer_and_ReceiveBuffer_must_correctly_cooperate_with_each_other() { var msgCount = 1000; var deliveryProbability = 0.5D; var referenceList = Enumerable.Range(0, msgCount).Select(x => Msg(x)).ToList(); var toSend = referenceList; var received = new List<Sequenced>(); var sndBuf = new AckedSendBuffer<Sequenced>(10); var rcvBuf = new AckedReceiveBuffer<Sequenced>(); var log = new List<string>(); var lastAck = new Ack(new SeqNo(-1)); Action<string> dbLog = log.Add; Action<int, double> senderSteps = (steps, p) => { var resends = new List<Sequenced>(sndBuf.Nacked.Concat(sndBuf.NonAcked).Take(steps)); var sends = new List<Sequenced>(); if (steps - resends.Count > 0) { var tmp = toSend.Take(steps - resends.Count).ToList(); toSend = toSend.Drop(steps - resends.Count).ToList(); sends = tmp; } foreach (var msg in resends.Concat(sends)) { if (sends.Contains(msg)) sndBuf = sndBuf.Buffer(msg); if (Happened(p)) { var del = rcvBuf.Receive(msg).ExtractDeliverable; rcvBuf = del.Buffer; dbLog(string.Format("{0} -- {1} --> {2}", sndBuf, msg, rcvBuf)); lastAck = del.Ack; received.AddRange(del.Deliverables); dbLog(string.Format("R: {0}", string.Join(",", received.Select(x => x.ToString())))); } else { dbLog(string.Format("{0} -- {1} --X {2}", sndBuf, msg, rcvBuf)); } } }; Action<double> receiverStep = (p) => { if (Happened(p)) { sndBuf = sndBuf.Acknowledge(lastAck); dbLog(string.Format("{0} <-- {1} -- {2}", sndBuf, lastAck, rcvBuf)); } else { dbLog(string.Format("{0} X-- {1} -- {2}", sndBuf, lastAck, rcvBuf)); } }; //Dropping phase global::System.Diagnostics.Debug.WriteLine("Starting unreliable delivery for {0} messages, with delivery probably P = {1}", msgCount, deliveryProbability); var nextSteps = msgCount*2; while (nextSteps > 0) { var s = Geom(0.3, limit: 5); senderSteps(s, deliveryProbability); receiverStep(deliveryProbability); nextSteps--; } global::System.Diagnostics.Debug.WriteLine("Successfully delivered {0} messages from {1}", received.Count, msgCount); global::System.Diagnostics.Debug.WriteLine("Entering reliable phase"); //Finalizing phase for (var i = 1; i <= msgCount; i++) { senderSteps(1, 1.0); receiverStep(1.0); } if (!received.SequenceEqual(referenceList)) { global::System.Diagnostics.Debug.WriteLine(string.Join(Environment.NewLine, log)); global::System.Diagnostics.Debug.WriteLine("Received: "); global::System.Diagnostics.Debug.WriteLine(string.Join(Environment.NewLine, received.Select(x => x.ToString()))); Assert.True(false,"Not all messages were received"); } global::System.Diagnostics.Debug.WriteLine("All messages have been successfully delivered"); }
public void ReceiveBuffer_must_be_able_to_correctly_merge_with_another_receive_buffer() { var buf1 = new AckedReceiveBuffer<Sequenced>(); var buf2 = new AckedReceiveBuffer<Sequenced>(); var msg0 = Msg(0); var msg1a = Msg(1); var msg1b = Msg(1); var msg2 = Msg(2); var msg3 = Msg(3); var buf = buf1.Receive(msg1a).Receive(msg2).MergeFrom(buf2.Receive(msg1b).Receive(msg3)); var d = buf.Receive(msg0).ExtractDeliverable; Assert.True(d.Deliverables.SequenceEqual(new []{ msg0, msg1b, msg2, msg3 })); Assert.Equal(new SeqNo(3), d.Ack.CumulativeAck); }
public void ReceiveBuffer_must_handle_duplicate_arrivals_correctly() { var buf = new AckedReceiveBuffer<Sequenced>(); var msg0 = Msg(0); var msg1 = Msg(1); var msg2 = Msg(2); var buf2 = buf.Receive(msg0).Receive(msg1).Receive(msg2).ExtractDeliverable.Buffer; var buf3 = buf2.Receive(msg0).Receive(msg1).Receive(msg2); var d = buf3.ExtractDeliverable; Assert.True(d.Deliverables.Count == 0); Assert.Equal(new SeqNo(2), d.Ack.CumulativeAck); }
public void ReceiveBuffer_must_enqueue_message_in_buffer_if_needed_return_the_list_of_deliverable_messages_and_acks() { var b0 = new AckedReceiveBuffer<Sequenced>(); var msg0 = Msg(0); var msg1 = Msg(1); var msg2 = Msg(2); var msg3 = Msg(3); var msg4 = Msg(4); var msg5 = Msg(5); var d1 = b0.Receive(msg1).ExtractDeliverable; Assert.True(d1.Deliverables.Count == 0); Assert.Equal(new SeqNo(1), d1.Ack.CumulativeAck); Assert.True(d1.Ack.Nacks.SequenceEqual(new[]{ new SeqNo(0) })); var b1 = d1.Buffer; var d2 = b1.Receive(msg0).ExtractDeliverable; Assert.True(d2.Deliverables.SequenceEqual(new[] { msg0, msg1 })); Assert.Equal(new SeqNo(1), d2.Ack.CumulativeAck); var b3 = d2.Buffer; var d3 = b3.Receive(msg4).ExtractDeliverable; Assert.True(d3.Deliverables.Count == 0); Assert.Equal(new SeqNo(4), d3.Ack.CumulativeAck); Assert.True(d3.Ack.Nacks.SequenceEqual(new[] { new SeqNo(2), new SeqNo(3) })); var b4 = d3.Buffer; var d4 = b4.Receive(msg2).ExtractDeliverable; Assert.True(d4.Deliverables.SequenceEqual(new[] { msg2 })); Assert.Equal(new SeqNo(4), d4.Ack.CumulativeAck); Assert.True(d4.Ack.Nacks.SequenceEqual(new[] { new SeqNo(3) })); var b5 = d4.Buffer; var d5 = b5.Receive(msg5).ExtractDeliverable; Assert.True(d5.Deliverables.Count == 0); Assert.Equal(new SeqNo(5), d5.Ack.CumulativeAck); Assert.True(d5.Ack.Nacks.SequenceEqual(new[] { new SeqNo(3) })); var b6 = d5.Buffer; var d6 = b6.Receive(msg3).ExtractDeliverable; Assert.True(d6.Deliverables.SequenceEqual(new[] { msg3, msg4, msg5 })); Assert.Equal(new SeqNo(5), d6.Ack.CumulativeAck); }
private void Reading() { Receive<Disassociated>(disassociated => HandleDisassociated(disassociated.Info)); Receive<InboundPayload>(inbound => { var payload = inbound.Payload; if (payload.Length > Transport.MaximumPayloadBytes) { var reason = new OversizedPayloadException( string.Format("Discarding oversized payload received: max allowed size {0} bytes, actual size {1} bytes.", Transport.MaximumPayloadBytes, payload.Length)); _log.Error(reason, "Transient error while reading from association (association remains live)"); } else { var ackAndMessage = TryDecodeMessageAndAck(payload); if (ackAndMessage.AckOption != null && _reliableDeliverySupervisor != null) _reliableDeliverySupervisor.Tell(ackAndMessage.AckOption); if (ackAndMessage.MessageOption != null) { if (ackAndMessage.MessageOption.ReliableDeliveryEnabled) { _ackedReceiveBuffer = _ackedReceiveBuffer.Receive(ackAndMessage.MessageOption); DeliverAndAck(); } else { _msgDispatch.Dispatch(ackAndMessage.MessageOption.Recipient, ackAndMessage.MessageOption.RecipientAddress, ackAndMessage.MessageOption.SerializedMessage, ackAndMessage.MessageOption.SenderOptional); } } } }); Receive<EndpointWriter.StopReading>(stop => { SaveState(); Become(NotReading); stop.ReplyTo.Tell(new EndpointWriter.StoppedReading(stop.Writer)); }); }
protected override void OnReceive(object message) { if (message is Disassociated) { HandleDisassociated((message as Disassociated).Info); } else if (message is InboundPayload) { var payload = ((InboundPayload)message).Payload; if (payload.Length > Transport.MaximumPayloadBytes) { var reason = new OversizedPayloadException( string.Format("Discarding oversized payload received: max allowed size {0} bytes, actual size {1} bytes.", Transport.MaximumPayloadBytes, payload.Length)); _log.Error(reason, "Transient error while reading from association (association remains live)"); } else { var ackAndMessage = TryDecodeMessageAndAck(payload); if (ackAndMessage.AckOption != null && _reliableDeliverySupervisor != null) _reliableDeliverySupervisor.Tell(ackAndMessage.AckOption); if (ackAndMessage.MessageOption != null) { if (ackAndMessage.MessageOption.ReliableDeliveryEnabled) { _ackedReceiveBuffer = _ackedReceiveBuffer.Receive(ackAndMessage.MessageOption); DeliverAndAck(); } else { _msgDispatch.Dispatch(ackAndMessage.MessageOption.Recipient, ackAndMessage.MessageOption.RecipientAddress, ackAndMessage.MessageOption.SerializedMessage, ackAndMessage.MessageOption.SenderOptional); } } } } else if (message is EndpointWriter.StopReading) { var stop = message as EndpointWriter.StopReading; SaveState(); Context.Become(NotReading); stop.ReplyTo.Tell(new EndpointWriter.StoppedReading(stop.Writer)); } else { Unhandled(message); } }