INTERNAL API
Inheritance: ReceiveActor
Beispiel #1
0
 private void TryBuffer(EndpointManager.Send s)
 {
     try
     {
         _resendBuffer = _resendBuffer.Buffer(s);
     }
     catch (Exception ex)
     {
         throw new HopelessAssociation(_localAddress, _remoteAddress, Uid, ex);
     }
 }
Beispiel #2
0
 private void UpdateSavedState(EndpointManager.Link key, EndpointManager.ResendState expectedState)
 {
     if (expectedState == null)
     {
         if (_receiveBuffers.ContainsKey(key))
         {
             var updatedValue = new EndpointManager.ResendState(_uid, _ackedReceiveBuffer);
             _receiveBuffers.AddOrUpdate(key, updatedValue, (link, state) => updatedValue);
             UpdateSavedState(key, updatedValue);
         }
     }
     else
     {
         var canReplace = _receiveBuffers.ContainsKey(key) && _receiveBuffers[key].Equals(expectedState);
         if (canReplace)
         {
             _receiveBuffers[key] = Merge(new EndpointManager.ResendState(_uid, _ackedReceiveBuffer),
                 expectedState);
         }
         else
         {
             EndpointManager.ResendState previousValue;
             _receiveBuffers.TryGetValue(key, out previousValue);
             UpdateSavedState(key, previousValue);
         }
     }
 }
Beispiel #3
0
 private void HandleSend(EndpointManager.Send send)
 {
     if (send.Message is ISystemMessage)
     {
         var sequencedSend = send.Copy(NextSeq());
         TryBuffer(sequencedSend);
         //If we have not confirmed the remote UID we cannot transfer the system message at this point, so just buffer it.
         // GotUid will kick ResendAll causing the messages to be properly written.
         if (UidConfirmed) _writer.Tell(sequencedSend);
     }
     else
     {
         _writer.Tell(send);
     }
 }
Beispiel #4
0
 private EndpointManager.ResendState Merge(EndpointManager.ResendState current,
     EndpointManager.ResendState oldState)
 {
     if (current.Uid == oldState.Uid) return new EndpointManager.ResendState(_uid, oldState.Buffer.MergeFrom(current.Buffer));
     return current;
 }
Beispiel #5
0
        private bool WriteSend(EndpointManager.Send send)
        {
            try
            {
                if (_handle == null)
                    throw new EndpointException(
                        "Internal error: Endpoint is in state Writing, but no association handle is present.");
                if (_provider.RemoteSettings.LogSend)
                {
                    var msgLog = string.Format("RemoteMessage: {0} to [{1}]<+[{2}] from [{3}]", send.Message,
                        send.Recipient, send.Recipient.Path, send.SenderOption ?? _system.DeadLetters);
                    _log.Debug(msgLog);
                }

                var pdu = _codec.ConstructMessage(send.Recipient.LocalAddressToUse, send.Recipient,
                    SerializeMessage(send.Message), send.SenderOption, send.Seq, _lastAck);

                //todo: RemoteMetrics https://github.com/akka/akka/blob/dc0547dd73b54b5de9c3e0b45a21aa865c5db8e2/akka-remote/src/main/scala/akka/remote/Endpoint.scala#L742

                //todo: max payload size validation

                var ok = _handle.Write(pdu);

                if (ok)
                {
                    _ackDeadline = NewAckDeadline();
                    _lastAck = null;
                    return true;
                }

                return false;
            }
            catch (SerializationException ex)
            {
                _log.Error(ex, "Transient association error (association remains live)");
                return true;
            }
            catch (EndpointException ex)
            {
                PublishAndThrow(ex, LogLevel.ErrorLevel);
            }
            catch (Exception ex)
            {
                PublishAndThrow(new EndpointException("Failed to write message to the transport", ex),
                    LogLevel.ErrorLevel);
            }

            return false;
        }
        /// <summary>
        /// Internal function used for filtering endpoints that need to be pruned due to non-recovery past their deadlines
        /// </summary>
        private static bool PruneFilterFunction(EndpointManager.EndpointPolicy policy)
        {
            var rValue = true;

            policy.Match()
                .With<EndpointManager.Gated>(g => rValue = g.TimeOfRelease.HasTimeLeft)
                .With<EndpointManager.Quarantined>(q => rValue = q.Deadline.HasTimeLeft)
                .Default(msg => rValue = true);

            return rValue;
        }
Beispiel #7
0
 private void HandleSend(EndpointManager.Send send)
 {
     if (send.Message is ISystemMessage)
     {
         var sequencedSend = send.Copy(NextSeq());
         TryBuffer(sequencedSend);
         // If we have not confirmed the remote UID we cannot transfer the system message at this point just buffer it.
         // GotUid will kick ResendAll() causing the messages to be properly written.
         // Flow control by not sending more when we already have many outstanding.
         if (UidConfirmed && _resendBuffer.NonAcked.Count <= _settings.SysResendLimit) _writer.Tell(sequencedSend);
     }
     else
     {
         _writer.Tell(send);
     }
 }
Beispiel #8
0
        private bool WriteSend(EndpointManager.Send send)
        {
            try
            {
                if (_handle == null)
                    throw new EndpointException(
                        "Internal error: Endpoint is in state Writing, but no association handle is present.");
                if (_provider.RemoteSettings.LogSend)
                {
                    _log.Debug("RemoteMessage: {0} to [{1}]<+[{2}] from [{3}]", send.Message,
                        send.Recipient, send.Recipient.Path, send.SenderOption ?? _system.DeadLetters);
                }

                var pdu = _codec.ConstructMessage(send.Recipient.LocalAddressToUse, send.Recipient,
                    SerializeMessage(send.Message), send.SenderOption, send.Seq, _lastAck);

                _remoteMetrics.LogPayloadBytes(send.Message, pdu.Length);

                if (pdu.Length > Transport.MaximumPayloadBytes)
                {
                    var reason = new OversizedPayloadException(
                        string.Format("Discarding oversized payload sent to {0}: max allowed size {1} bytes, actual size of encoded {2} was {3} bytes.",
                            send.Recipient,
                            Transport.MaximumPayloadBytes,
                            send.Message.GetType(),
                            pdu.Length));
                    _log.Error(reason, "Transient association error (association remains live)");
                    return true;
                }
                else
                {
                    var ok = _handle.Write(pdu);

                    if (ok)
                    {
                        _ackDeadline = NewAckDeadline();
                        _lastAck = null;
                        return true;
                    }
                }
                return false;
            }
            catch (SerializationException ex)
            {
                _log.Error(ex, "Transient association error (association remains live)");
                return true;
            }
            catch (EndpointException ex)
            {
                PublishAndThrow(ex, LogLevel.ErrorLevel);
            }
            catch (Exception ex)
            {
                PublishAndThrow(new EndpointException("Failed to write message to the transport", ex),
                    LogLevel.ErrorLevel);
            }

            return false;
        }