コード例 #1
0
ファイル: ReplayFilter.cs プロジェクト: yyp2003net/akka.net
 private void SendBuffered()
 {
     foreach (var message in _buffer)
     {
         PersistentActor.Tell(message, ActorRefs.NoSender);
     }
     _buffer.Clear();
 }
コード例 #2
0
 public void PersistentActorTest()
 {
     TestLauncherActor.Test(() =>
     {
         var service    = new MemoizePersistentService <string>();
         var persistent = new PersistentActor <string>(service, "TestActor");
         persistent.SendMessage(new EventSourceTest("A"));
         persistent.SendMessage(new EventSourceTest("B"));
         persistent.SendMessage(new EventSourceTest("C"));
         Assert.AreEqual("C", persistent.GetCurrent().Result());
         var persistent2 = new PersistentActor <string>(service, "TestActor");
         persistent2.Reload();
         Assert.AreEqual("C", persistent2.GetCurrent().Result());
     });
 }
コード例 #3
0
ファイル: ReplayFilter.cs プロジェクト: ziez/akka.net
 private void Fail(IllegalStateException cause)
 {
     _buffer.Clear();
     PersistentActor.Tell(new ReplayMessagesFailure(cause), ActorRefs.NoSender);
     Context.Become(message =>
     {
         if (message is ReplayedMessage)
         {
             // discard
         }
         else if (message is RecoverySuccess || message is ReplayMessagesFailure)
         {
             Context.Stop(Self);
         }
         else
         {
             return(false);
         }
         return(true);
     });
 }
コード例 #4
0
ファイル: ReplayFilter.cs プロジェクト: yyp2003net/akka.net
        /// <summary>
        /// TBD
        /// </summary>
        /// <param name="message">TBD</param>
        /// <exception cref="ArgumentException">
        /// This exception is thrown when the <see cref="Mode"/> is set to <see cref="ReplayFilterMode.Disabled"/>.
        /// </exception>
        /// <exception cref="IllegalStateException">
        /// This exception is thrown when either the replayed event is in the wrong order or from an old writer.
        /// </exception>
        /// <returns>TBD</returns>
        protected override bool Receive(object message)
        {
            if (message is ReplayedMessage)
            {
                var r = (ReplayedMessage)message;
                if (DebugEnabled && _log.IsDebugEnabled)
                {
                    _log.Debug($"Replay: {r.Persistent}");
                }

                try
                {
                    if (_buffer.Count == WindowSize)
                    {
                        var msg = _buffer.First;
                        _buffer.RemoveFirst();
                        PersistentActor.Tell(msg.Value, ActorRefs.NoSender);
                    }

                    if (r.Persistent.WriterGuid.Equals(_writerUuid))
                    {
                        // from same writer
                        if (r.Persistent.SequenceNr < _sequenceNr)
                        {
                            var errMsg = $@"Invalid replayed event [sequenceNr={r.Persistent.SequenceNr}, writerUUID={r.Persistent.WriterGuid}] as
                                            the sequenceNr should be equal to or greater than already-processed event [sequenceNr={_sequenceNr}, writerUUID={_writerUuid}] from the same writer, for the same persistenceId [{r.Persistent.PersistenceId}].
                                            Perhaps, events were journaled out of sequence, or duplicate PersistentId for different entities?";
                            LogIssue(errMsg);
                            switch (Mode)
                            {
                            case ReplayFilterMode.RepairByDiscardOld:
                                //discard
                                break;

                            case ReplayFilterMode.Fail:
                                throw new IllegalStateException(errMsg);

                            case ReplayFilterMode.Warn:
                                _buffer.AddLast(r);
                                break;

                            case ReplayFilterMode.Disabled:
                                throw new ArgumentException("Mode must not be Disabled");
                            }
                        }
                        else
                        {
                            // note that it is alright with == _sequenceNr, since such may be emitted by EventSeq
                            _buffer.AddLast(r);
                            _sequenceNr = r.Persistent.SequenceNr;
                        }
                    }
                    else if (_oldWriters.Contains(r.Persistent.WriterGuid))
                    {
                        // from old writer
                        var errMsg = $@"Invalid replayed event [sequenceNr={r.Persistent.SequenceNr}, writerUUID={r.Persistent.WriterGuid}].
                                        There was already a newer writer whose last replayed event was [sequenceNr={_sequenceNr}, writerUUID={_writerUuid}] for the same persistenceId [{r.Persistent.PersistenceId}].
                                        Perhaps, the old writer kept journaling messages after the new writer created, or duplicate PersistentId for different entities?";
                        LogIssue(errMsg);
                        switch (Mode)
                        {
                        case ReplayFilterMode.RepairByDiscardOld:
                            //discard
                            break;

                        case ReplayFilterMode.Fail:
                            throw new IllegalStateException(errMsg);

                        case ReplayFilterMode.Warn:
                            _buffer.AddLast(r);
                            break;

                        case ReplayFilterMode.Disabled:
                            throw new ArgumentException("Mode must not be Disabled");
                        }
                    }
                    else
                    {
                        // from new writer
                        if (!string.IsNullOrEmpty(_writerUuid))
                        {
                            _oldWriters.AddLast(_writerUuid);
                        }
                        if (_oldWriters.Count > MaxOldWriters)
                        {
                            _oldWriters.RemoveFirst();
                        }
                        _writerUuid = r.Persistent.WriterGuid;
                        _sequenceNr = r.Persistent.SequenceNr;

                        // clear the buffer from messages from other writers with higher SequenceNr
                        var node = _buffer.First;
                        while (node != null)
                        {
                            var next = node.Next;
                            var msg  = node.Value;
                            if (msg.Persistent.SequenceNr >= _sequenceNr)
                            {
                                var errMsg = $@"Invalid replayed event [sequenceNr=${r.Persistent.SequenceNr}, writerUUID=${r.Persistent.WriterGuid}] from a new writer.
                                                An older writer already sent an event [sequenceNr=${msg.Persistent.SequenceNr}, writerUUID=${msg.Persistent.WriterGuid}] whose sequence number was equal or greater for the same persistenceId [${r.Persistent.PersistenceId}].
                                                Perhaps, the new writer journaled the event out of sequence, or duplicate PersistentId for different entities?";
                                LogIssue(errMsg);
                                switch (Mode)
                                {
                                case ReplayFilterMode.RepairByDiscardOld:
                                    _buffer.Remove(node);
                                    //discard
                                    break;

                                case ReplayFilterMode.Fail:
                                    throw new IllegalStateException(errMsg);

                                case ReplayFilterMode.Warn:
                                    // keep
                                    break;

                                case ReplayFilterMode.Disabled:
                                    throw new ArgumentException("Mode must not be Disabled");
                                }
                            }
                            node = next;
                        }
                        _buffer.AddLast(r);
                    }
                }
                catch (IllegalStateException ex)
                {
                    if (Mode == ReplayFilterMode.Fail)
                    {
                        Fail(ex);
                    }
                    else
                    {
                        throw;
                    }
                }
            }
            else if (message is RecoverySuccess || message is ReplayMessagesFailure)
            {
                if (DebugEnabled)
                {
                    _log.Debug($"Replay completed: {message}");
                }

                SendBuffered();
                PersistentActor.Tell(message, ActorRefs.NoSender);
                Context.Stop(Self);
            }
            else
            {
                return(false);
            }
            return(true);
        }
コード例 #5
0
ファイル: ReplayFilter.cs プロジェクト: ziez/akka.net
        /// <summary>
        /// TBD
        /// </summary>
        /// <param name="message">TBD</param>
        /// <exception cref="ArgumentException">TBD</exception>
        /// <exception cref="IllegalStateException">TBD</exception>
        /// <returns>TBD</returns>
        protected override bool Receive(object message)
        {
            if (message is ReplayedMessage)
            {
                var r = (ReplayedMessage)message;
                if (DebugEnabled && _log.IsDebugEnabled)
                {
                    _log.Debug("Replay: " + r.Persistent);
                }
                try
                {
                    if (_buffer.Count == WindowSize)
                    {
                        var msg = _buffer.First;
                        _buffer.RemoveFirst();
                        PersistentActor.Tell(msg.Value, ActorRefs.NoSender);
                    }

                    if (r.Persistent.WriterGuid.Equals(_writerUuid))
                    {
                        // from same writer
                        if (r.Persistent.SequenceNr < _sequenceNr)
                        {
                            var errMsg =
                                string.Format(
                                    "Invalid replayed event [{0}] in wrong order from " +
                                    "writer [{1}] with PersistenceId [{2}]", r.Persistent.SequenceNr,
                                    r.Persistent.WriterGuid, r.Persistent.PersistenceId);
                            LogIssue(errMsg);
                            switch (Mode)
                            {
                            case ReplayFilterMode.RepairByDiscardOld:
                                //discard
                                break;

                            case ReplayFilterMode.Fail:
                                throw new IllegalStateException(errMsg);

                            case ReplayFilterMode.Warn:
                                _buffer.AddLast(r);
                                break;

                            case ReplayFilterMode.Disabled:
                                throw new ArgumentException("Mode must not be Disabled");
                            }
                        }
                        else
                        {
                            // note that it is alright with == _sequenceNr, since such may be emitted by EventSeq
                            _buffer.AddLast(r);
                            _sequenceNr = r.Persistent.SequenceNr;
                        }
                    }
                    else if (_oldWriters.Contains(r.Persistent.WriterGuid))
                    {
                        // from old writer
                        var errMsg =
                            string.Format(
                                "Invalid replayed event [{0}] from old writer [{1}] with PersistenceId [{2}]",
                                r.Persistent.SequenceNr, r.Persistent.WriterGuid, r.Persistent.PersistenceId);
                        LogIssue(errMsg);
                        switch (Mode)
                        {
                        case ReplayFilterMode.RepairByDiscardOld:
                            //discard
                            break;

                        case ReplayFilterMode.Fail:
                            throw new IllegalStateException(errMsg);

                        case ReplayFilterMode.Warn:
                            _buffer.AddLast(r);
                            break;

                        case ReplayFilterMode.Disabled:
                            throw new ArgumentException("Mode must not be Disabled");
                        }
                    }
                    else
                    {
                        // from new writer
                        if (!string.IsNullOrEmpty(_writerUuid))
                        {
                            _oldWriters.AddLast(_writerUuid);
                        }
                        if (_oldWriters.Count > MaxOldWriters)
                        {
                            _oldWriters.RemoveFirst();
                        }
                        _writerUuid = r.Persistent.WriterGuid;
                        _sequenceNr = r.Persistent.SequenceNr;

                        // clear the buffer from messages from other writers with higher SequenceNr
                        var node = _buffer.First;
                        while (node != null)
                        {
                            var next = node.Next;
                            var msg  = node.Value;
                            if (msg.Persistent.SequenceNr >= _sequenceNr)
                            {
                                var errMsg =
                                    string.Format(
                                        "Invalid replayed event [{0}] in buffer from old writer [{1}] with PersistenceId [{2}]",
                                        r.Persistent.SequenceNr, r.Persistent.WriterGuid, r.Persistent.PersistenceId);
                                LogIssue(errMsg);
                                switch (Mode)
                                {
                                case ReplayFilterMode.RepairByDiscardOld:
                                    _buffer.Remove(node);
                                    //discard
                                    break;

                                case ReplayFilterMode.Fail:
                                    throw new IllegalStateException(errMsg);

                                case ReplayFilterMode.Warn:
                                    // keep
                                    break;

                                case ReplayFilterMode.Disabled:
                                    throw new ArgumentException("Mode must not be Disabled");
                                }
                            }
                            node = next;
                        }
                        _buffer.AddLast(r);
                    }
                }
                catch (IllegalStateException ex)
                {
                    if (Mode == ReplayFilterMode.Fail)
                    {
                        Fail(ex);
                    }
                    else
                    {
                        throw;
                    }
                }
            }
            else if (message is RecoverySuccess || message is ReplayMessagesFailure)
            {
                SendBuffered();
                PersistentActor.Tell(message, ActorRefs.NoSender);
                Context.Stop(Self);
            }
            else
            {
                return(false);
            }
            return(true);
        }