Ejemplo n.º 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();
            }
        }