Exemplo n.º 1
0
        // Hides the base SetResult method which we need to override
        // This method is called when the message is actually delivered to a ReceiveAsync call
        // The update to the CloseMessageSequenceNumber property of Inbound is transactional
        internal async Task SetResult(InboundBaseStreamWireMessage message)
        {
            var closeSeqNumber = this.stream.CloseMessageSequenceNumber;

            if (message.Kind == StreamWireProtocolMessageKind.CloseStream)
            {
                // The close message can be a repeat in recovery cases, but the close sequence number must be unique
                // It is also possible that the transaction surrounding this ReceiveAsync will abort and the message
                // will not in fact be consumed -- and will be received again, but the close sequence number must be unique
                Diagnostics.Assert(
                    closeSeqNumber == StreamConstants.InitialValueOfLastSequenceNumberInStream || closeSeqNumber == message.MessageSequenceNumber,
                    "{0} TraceId::{1} encountered multiple close sequence number values {2} and {3}",
                    this.stream.Tracer,
                    this.traceId,
                    closeSeqNumber,
                    message.MessageSequenceNumber);

                try
                {
                    // this method is idempotent; the close sequence number for a stream is invariant
                    await this.stream.SetCloseMessageSequenceNumber(message.MessageSequenceNumber, this.transactionContext);

                    await this.stream.CloseInboundStream(this.transactionContext);
                }
                catch (Exception e)
                {
                    if (e is FabricObjectClosedException)
                    {
                        FabricEvents.Events.DataMessageDelivery(
                            string.Format(CultureInfo.InvariantCulture, "ObjectClosed@{0}{1}", this.traceId, this.stream.TraceType),
                            this.stream.StreamIdentity.ToString(),
                            message.MessageSequenceNumber,
                            this.transactionContext.Id.ToString());

                        this.TrySetException(e);
                        return;
                    }
                    if (e is FabricNotPrimaryException)
                    {
                        FabricEvents.Events.DataMessageDelivery(
                            string.Format(CultureInfo.InvariantCulture, "NotPrimary@{0}{1}", this.traceId, this.stream.TraceType),
                            this.stream.StreamIdentity.ToString(),
                            message.MessageSequenceNumber,
                            this.transactionContext.Id.ToString());

                        this.TrySetException(e);
                        return;
                    }
                    if (e is FabricNotReadableException)
                    {
                        FabricEvents.Events.DataMessageDelivery(
                            string.Format(CultureInfo.InvariantCulture, "NotReadable@{0}{1}", this.traceId, this.stream.TraceType),
                            this.stream.StreamIdentity.ToString(),
                            message.MessageSequenceNumber,
                            this.transactionContext.Id.ToString());

                        this.TrySetException(e);
                        return;
                    }

                    Tracing.WriteExceptionAsError(
                        "DataMessageDelivery.Failure",
                        e,
                        "Partition::Replica {0} TraceId: {1} MessageNumber: {2} TransactionId: {3}",
                        this.stream.TraceType,
                        this.traceId,
                        message.MessageSequenceNumber,
                        this.transactionContext.Id);
                    Diagnostics.Assert(
                        false,
                        "Unexpected Exception In {0} TraceId: {1} MessageNumber: {2} TransactionId: {3}",
                        this.stream.TraceType,
                        this.traceId,
                        message.MessageSequenceNumber,
                        this.transactionContext.Id);
                }
            }
            else
            {
                Diagnostics.Assert(
                    closeSeqNumber == StreamConstants.InitialValueOfLastSequenceNumberInStream || closeSeqNumber > message.MessageSequenceNumber,
                    "{0} received payload message with sequence number {1} which is greater than the close sequence number {2}",
                    this.stream.Tracer,
                    message.MessageSequenceNumber,
                    closeSeqNumber);
            }

            var setResultSuccess = this.TrySetResult(message);

            if (setResultSuccess)
            {
                FabricEvents.Events.DataMessageDelivery(
                    "Success::" + this.traceId + "@" + this.stream.TraceType,
                    this.stream.StreamIdentity.ToString(),
                    message.MessageSequenceNumber,
                    this.transactionContext.Id.ToString());
            }
            else
            {
                FabricEvents.Events.DataMessageDelivery(
                    "Failure::" + this.traceId + "@" + this.stream.TraceType,
                    this.stream.StreamIdentity.ToString(),
                    message.MessageSequenceNumber,
                    this.transactionContext.Id.ToString());
            }
        }