示例#1
0
        void IHandle <StorageMessage.WriteCommit> .Handle(StorageMessage.WriteCommit message)
        {
            Interlocked.Decrement(ref FlushMessagesInQueue);
            try
            {
                var commitPos = Writer.Checkpoint.ReadNonFlushed();
                var result    = ReadIndex.CheckCommitStartingAt(message.TransactionPosition, commitPos);
                switch (result.Decision)
                {
                case CommitDecision.Ok:
                {
                    var commit = WriteCommitWithRetry(LogRecord.Commit(commitPos,
                                                                       message.CorrelationId,
                                                                       message.TransactionPosition,
                                                                       result.CurrentVersion + 1));
                    ReadIndex.Commit(commit);
                    break;
                }

                case CommitDecision.WrongExpectedVersion:
                    message.Envelope.ReplyWith(new StorageMessage.WrongExpectedVersion(message.CorrelationId));
                    break;

                case CommitDecision.Deleted:
                    message.Envelope.ReplyWith(new StorageMessage.StreamDeleted(message.CorrelationId));
                    break;

                case CommitDecision.Idempotent:
                    message.Envelope.ReplyWith(new StorageMessage.AlreadyCommitted(message.CorrelationId,
                                                                                   result.EventStreamId,
                                                                                   result.StartEventNumber,
                                                                                   result.EndEventNumber));
                    break;

                case CommitDecision.CorruptedIdempotency:
                    // in case of corrupted idempotency (part of transaction is ok, other is different)
                    // then we can say that the transaction is not idempotent, so WrongExpectedVersion is ok answer
                    message.Envelope.ReplyWith(new StorageMessage.WrongExpectedVersion(message.CorrelationId));
                    break;

                case CommitDecision.InvalidTransaction:
                    message.Envelope.ReplyWith(new StorageMessage.InvalidTransaction(message.CorrelationId));
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }
            }
            catch (Exception exc)
            {
                Log.ErrorException(exc, "Exception in writer.");
                throw;
            }
            finally
            {
                Flush();
            }
        }
示例#2
0
        void IHandle <StorageMessage.WriteCommit> .Handle(StorageMessage.WriteCommit message)
        {
            Interlocked.Decrement(ref FlushMessagesInQueue);
            try
            {
                var result = ReadIndex.CheckCommitStartingAt(message.PrepareStartPosition);
                switch (result.Decision)
                {
                case CommitDecision.Ok:
                {
                    var commit = WriteCommitWithRetry(LogRecord.Commit(Writer.Checkpoint.ReadNonFlushed(),
                                                                       message.CorrelationId,
                                                                       message.PrepareStartPosition,
                                                                       result.CurrentVersion + 1));
                    ReadIndex.Commit(commit);
                    break;
                }

                case CommitDecision.WrongExpectedVersion:
                    message.Envelope.ReplyWith(new StorageMessage.WrongExpectedVersion(message.CorrelationId));
                    break;

                case CommitDecision.Deleted:
                    message.Envelope.ReplyWith(new StorageMessage.StreamDeleted(message.CorrelationId));
                    break;

                case CommitDecision.Idempotent:
                    message.Envelope.ReplyWith(new StorageMessage.AlreadyCommitted(message.CorrelationId,
                                                                                   result.EventStreamId,
                                                                                   result.StartEventNumber,
                                                                                   result.EndEventNumber));
                    break;

                case CommitDecision.CorruptedIdempotency:
                    //TODO AN add messages and error code for invalid idempotent request
                    throw new Exception("The request was partially committed and other part is different.");

                case CommitDecision.InvalidTransaction:
                    message.Envelope.ReplyWith(new StorageMessage.InvalidTransaction(message.CorrelationId));
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }
            }
            finally
            {
                Flush();
            }
        }
示例#3
0
        public void FSMSpeedTest1()
        {
            var       fsm        = CreateFSM();
            var       msg        = new StorageMessage.WriteCommit(Guid.NewGuid(), new NoopEnvelope(), 0);
            const int iterations = 1000000;

            var sw = Stopwatch.StartNew();

            for (int i = 0; i < iterations; ++i)
            {
                fsm.Handle(msg);
            }

            sw.Stop();

            Console.WriteLine("Elapsed: {0} ({1} per item).", sw.Elapsed, sw.ElapsedMilliseconds / (float)iterations);
        }
示例#4
0
        void IHandle <StorageMessage.WriteCommit> .Handle(StorageMessage.WriteCommit message)
        {
            Interlocked.Decrement(ref FlushMessagesInQueue);
            try
            {
                var commitPos   = Writer.Checkpoint.ReadNonFlushed();
                var commitCheck = _indexWriter.CheckCommitStartingAt(message.TransactionPosition, commitPos);
                if (commitCheck.Decision != CommitDecision.Ok)
                {
                    ActOnCommitCheckFailure(message.Envelope, message.CorrelationId, commitCheck);
                    return;
                }


                var commit = WriteCommitWithRetry(LogRecord.Commit(commitPos,
                                                                   message.CorrelationId,
                                                                   message.TransactionPosition,
                                                                   commitCheck.CurrentVersion + 1));

                bool softUndeleteMetastream = SystemStreams.IsMetastream(commitCheck.EventStreamId)
                                              &&
                                              _indexWriter.IsSoftDeleted(
                    SystemStreams.OriginalStreamOf(commitCheck.EventStreamId));

                _indexWriter.PreCommit(commit);

                if (commitCheck.IsSoftDeleted)
                {
                    SoftUndeleteStream(commitCheck.EventStreamId, commitCheck.CurrentVersion + 1);
                }
                if (softUndeleteMetastream)
                {
                    SoftUndeleteMetastream(commitCheck.EventStreamId);
                }
            }
            catch (Exception exc)
            {
                Log.ErrorException(exc, "Exception in writer.");
                throw;
            }
            finally
            {
                Flush();
            }
        }
示例#5
0
        public void FSMSpeedTest2()
        {
            var bus = new InMemoryBus("a", true);

            bus.Subscribe(new AdHocHandler <StorageMessage.WriteCommit>(x => { }));
            bus.Subscribe(new AdHocHandler <Message>(x => { }));

            var       msg        = new StorageMessage.WriteCommit(Guid.NewGuid(), new NoopEnvelope(), 0);
            const int iterations = 1000000;

            var sw = Stopwatch.StartNew();

            for (int i = 0; i < iterations; ++i)
            {
                bus.Handle(msg);
            }

            sw.Stop();

            Console.WriteLine("Elapsed: {0} ({1} per item).", sw.Elapsed, sw.ElapsedMilliseconds / (float)iterations);
        }