Exemplo n.º 1
0
        protected static void SendMessageToNewSaga <TMessage>(ISagaPolicy <TSaga, TMessage> policy, TMessage message, Action <TSaga> consumerAction, Action <TSaga> removeAction)
        {
            TSaga saga;

            if (!policy.CreateSagaWhenMissing(message, out saga))
            {
                return;
            }

            if (_log.IsDebugEnabled)
            {
                _log.DebugFormat("Created saga [{0}] - {1}", typeof(TSaga).ToFriendlyName(), saga.CorrelationId);
            }

            try
            {
                lock (saga)
                    consumerAction(saga);

                if (policy.ShouldSagaBeRemoved(saga))
                {
                    removeAction(saga);
                }
            }
            catch (Exception ex)
            {
                var sex = new SagaException("Saga consumer exception", typeof(TSaga), typeof(TMessage), saga.CorrelationId, ex);
                if (_log.IsErrorEnabled)
                {
                    _log.Error("Existing Saga Exception: ", sex);
                }

                throw sex;
            }
        }
Exemplo n.º 2
0
        public Task Send(ConsumeContext <TData> context)
        {
            using (RetryPolicyContext <ConsumeContext <TData> > policyContext = _retryPolicy.CreatePolicyContext(context))
            {
                var exception = new SagaException("An existing saga instance was not found", typeof(TInstance), typeof(TData), context.CorrelationId ?? Guid
                                                  .Empty);

                if (!policyContext.CanRetry(exception, out RetryContext <ConsumeContext <TData> > retryContext))
                {
                    return(_finalPipe.Send(context));
                }

                int previousDeliveryCount = context.GetRedeliveryCount();
                for (int retryIndex = 0; retryIndex < previousDeliveryCount; retryIndex++)
                {
                    if (!retryContext.CanRetry(exception, out retryContext))
                    {
                        return(_finalPipe.Send(context));
                    }
                }

                var schedulerContext = context.GetPayload <MessageSchedulerContext>();

                MessageRedeliveryContext redeliveryContext = new ScheduleMessageRedeliveryContext <TData>(context, schedulerContext);

                var delay = retryContext.Delay ?? TimeSpan.Zero;

                return(redeliveryContext.ScheduleRedelivery(delay));
            }
        }
        /// <summary>
        ///     Creates new saga action.
        /// </summary>
        /// <exception cref="SagaException"> Thrown when a saga error condition occurs.</exception>
        /// <typeparam name="TMessage"> Type of the message.</typeparam>
        /// <param name="sagaId">   Identifier for the saga.</param>
        /// <param name="selector"> The selector.</param>
        /// <param name="policy">   The policy.</param>
        /// <returns>
        ///     The new new saga action&lt; t message&gt;
        /// </returns>
        Action <IConsumeContext <TMessage> > CreateNewSagaAction <TMessage>(
            Guid sagaId,
            InstanceHandlerSelector <TSaga, TMessage> selector,
            ISagaPolicy <TSaga, TMessage> policy)
            where TMessage : class
        {
            return(x =>
            {
                if (Log.IsDebugEnabled)
                {
                    Log.DebugFormat(
                        "SAGA: {0} Creating New {1} for {2}",
                        typeof(TSaga).ToFriendlyName(),
                        sagaId,
                        typeof(TMessage).ToFriendlyName());
                }

                try
                {
                    TSaga instance = policy.CreateInstance(x, sagaId);

                    foreach (var callback in selector(instance, x))
                    {
                        callback(x);
                    }

                    if (!policy.CanRemoveInstance(instance))
                    {
                        Collection.Insert(instance, WriteConcern.Acknowledged);
                    }
                    else
                    {
                        Collection.Save(instance, WriteConcern.Acknowledged);
                    }
                }
                catch (Exception ex)
                {
                    var sagaException = new SagaException(
                        "Create Saga Instance Exception",
                        typeof(TSaga),
                        typeof(TMessage),
                        sagaId,
                        ex);

                    if (Log.IsErrorEnabled)
                    {
                        Log.Error(sagaException);
                    }

                    throw sagaException;
                }
            });
        }
        /// <summary>
        ///     Use existing saga action.
        /// </summary>
        /// <exception cref="SagaException"> Thrown when a saga error condition occurs.</exception>
        /// <typeparam name="TMessage"> Type of the message.</typeparam>
        /// <param name="sagaId">   Identifier for the saga.</param>
        /// <param name="selector"> The selector.</param>
        /// <param name="policy">   The policy.</param>
        /// <param name="instance"> The instance.</param>
        /// <returns>
        ///     .
        /// </returns>
        Action <IConsumeContext <TMessage> > UseExistingSagaAction <TMessage>(
            Guid sagaId,
            InstanceHandlerSelector <TSaga, TMessage> selector,
            ISagaPolicy <TSaga, TMessage> policy,
            TSaga instance)
            where TMessage : class
        {
            return(x =>
            {
                if (Log.IsDebugEnabled)
                {
                    Log.DebugFormat(
                        "SAGA: {0} Using Existing {1} for {2}",
                        typeof(TSaga).ToFriendlyName(),
                        sagaId,
                        typeof(TMessage).ToFriendlyName());
                }

                try
                {
                    foreach (var callback in selector(instance, x))
                    {
                        callback(x);
                    }

                    if (policy.CanRemoveInstance(instance))
                    {
                        Collection.Remove(
                            GetMongoQuery(Queryable.Where(q => q.CorrelationId == sagaId)),
                            RemoveFlags.Single,
                            WriteConcern.Acknowledged);
                    }
                }
                catch (Exception ex)
                {
                    var sagaException = new SagaException(
                        "Existing Saga Instance Exception",
                        typeof(TSaga),
                        typeof(TMessage),
                        sagaId,
                        ex);
                    if (Log.IsErrorEnabled)
                    {
                        Log.Error(sagaException);
                    }

                    throw sagaException;
                }
            });
        }
Exemplo n.º 5
0
        protected static bool SendMessageToExistingSagas <TMessage>(IEnumerable <TSaga> existingSagas,
                                                                    ISagaPolicy <TSaga, TMessage> policy,
                                                                    Action <TSaga> consumerAction,
                                                                    TMessage message,
                                                                    Action <TSaga> removeAction)
        {
            int       sagaCount     = 0;
            Exception lastException = null;

            foreach (TSaga saga in existingSagas)
            {
                try
                {
                    sagaCount++;

                    if (_log.IsDebugEnabled)
                    {
                        _log.DebugFormat("Found saga [{0}] - {1}", typeof(TSaga).ToFriendlyName(), saga.CorrelationId);
                    }

                    policy.ForExistingSaga(message);

                    lock (saga)
                        consumerAction(saga);

                    if (policy.ShouldSagaBeRemoved(saga))
                    {
                        removeAction(saga);
                    }
                }
                catch (Exception ex)
                {
                    var sex = new SagaException("Saga consumer exception", typeof(TSaga), typeof(TMessage), saga.CorrelationId, ex);
                    if (_log.IsErrorEnabled)
                    {
                        _log.Error("Existing Saga Exception: ", sex);
                    }

                    lastException = sex;
                }
            }

            if (lastException != null)
            {
                throw lastException;
            }

            return(sagaCount > 0);
        }
        public async Task GivenAMongoDbSagaRepository_WhenSendingWithNullCorrelationId()
        {
            var context = new Mock<ConsumeContext<InitiateSimpleSaga>>();
            context.Setup(x => x.CorrelationId).Returns(default(Guid?));

            var repository = new MongoDbSagaRepository<SimpleSaga>(Mock.Of<IMongoDatabase>(), null);

            try
            {
                await repository.Send(context.Object, Mock.Of<ISagaPolicy<SimpleSaga, InitiateSimpleSaga>>(),
                    Mock.Of<IPipe<SagaConsumeContext<SimpleSaga, InitiateSimpleSaga>>>());
            }
            catch (SagaException exception)
            {
                _exception = exception;
            }
        }
Exemplo n.º 7
0
        public async Task GivenAMongoDbSagaRepository_WhenSendingWithNullCorrelationId()
        {
            var context = new Mock <ConsumeContext <InitiateSimpleSaga> >();

            context.Setup(x => x.CorrelationId).Returns(default(Guid?));

            var repository = new MongoDbSagaRepository <SimpleSaga>(Mock.Of <IMongoDatabase>(), null);

            try
            {
                await repository.Send(context.Object, Mock.Of <ISagaPolicy <SimpleSaga, InitiateSimpleSaga> >(), Mock.Of <IPipe <SagaConsumeContext <SimpleSaga, InitiateSimpleSaga> > >());
            }
            catch (SagaException exception)
            {
                _exception = exception;
            }
        }
        public async Task GivenADocumentDbSagaRepository_WhenSendingWithNullCorrelationId()
        {
            var context = new Mock <ConsumeContext <InitiateSimpleSaga> >();

            context.Setup(x => x.CorrelationId).Returns(default(Guid?));

            var repository = new DocumentDbSagaRepository <SimpleSagaResource>(Mock.Of <IDocumentClient>(), "sagaTest");

            try
            {
                await repository.Send(context.Object, Mock.Of <ISagaPolicy <SimpleSagaResource, InitiateSimpleSaga> >(),
                                      Mock.Of <IPipe <SagaConsumeContext <SimpleSagaResource, InitiateSimpleSaga> > >());
            }
            catch (SagaException exception)
            {
                _exception = exception;
            }
        }
Exemplo n.º 9
0
        public IEnumerable <Action <IConsumeContext <TMessage> > > GetSaga <TMessage>(IConsumeContext <TMessage> context,
                                                                                      Guid sagaId,
                                                                                      InstanceHandlerSelector <TSaga, TMessage>
                                                                                      selector,
                                                                                      ISagaPolicy <TSaga, TMessage> policy)
            where TMessage : class
        {
            using (ISession session = _sessionFactory.OpenSession())
                using (ITransaction transaction = session.BeginTransaction())
                {
                    var instance = session.Get <TSaga>(sagaId, LockMode.Upgrade);
                    if (instance == null)
                    {
                        if (policy.CanCreateInstance(context))
                        {
                            yield return(x =>
                            {
                                if (_log.IsDebugEnabled)
                                {
                                    _log.DebugFormat("SAGA: {0} Creating New {1} for {2}",
                                                     typeof(TSaga).ToFriendlyName(), sagaId,
                                                     typeof(TMessage).ToFriendlyName());
                                }

                                try
                                {
                                    instance = policy.CreateInstance(x, sagaId);

                                    foreach (var callback in selector(instance, x))
                                    {
                                        callback(x);
                                    }

                                    if (!policy.CanRemoveInstance(instance))
                                    {
                                        session.Save(instance);
                                    }
                                }
                                catch (Exception ex)
                                {
                                    var sex = new SagaException("Create Saga Instance Exception", typeof(TSaga),
                                                                typeof(TMessage), sagaId, ex);
                                    if (_log.IsErrorEnabled)
                                    {
                                        _log.Error(sex);
                                    }

                                    if (transaction.IsActive)
                                    {
                                        transaction.Rollback();
                                    }

                                    throw sex;
                                }
                            });
                        }
                        else
                        {
                            if (_log.IsDebugEnabled)
                            {
                                _log.DebugFormat("SAGA: {0} Ignoring Missing {1} for {2}", typeof(TSaga).ToFriendlyName(),
                                                 sagaId,
                                                 typeof(TMessage).ToFriendlyName());
                            }
                        }
                    }
                    else
                    {
                        if (policy.CanUseExistingInstance(context))
                        {
                            yield return(x =>
                            {
                                if (_log.IsDebugEnabled)
                                {
                                    _log.DebugFormat("SAGA: {0} Using Existing {1} for {2}",
                                                     typeof(TSaga).ToFriendlyName(), sagaId,
                                                     typeof(TMessage).ToFriendlyName());
                                }

                                try
                                {
                                    foreach (var callback in selector(instance, x))
                                    {
                                        callback(x);
                                    }

                                    if (policy.CanRemoveInstance(instance))
                                    {
                                        session.Delete(instance);
                                    }
                                }
                                catch (Exception ex)
                                {
                                    var sex = new SagaException("Existing Saga Instance Exception", typeof(TSaga),
                                                                typeof(TMessage), sagaId, ex);
                                    if (_log.IsErrorEnabled)
                                    {
                                        _log.Error(sex);
                                    }

                                    if (transaction.IsActive)
                                    {
                                        transaction.Rollback();
                                    }

                                    throw sex;
                                }
                            });
                        }
                        else
                        {
                            if (_log.IsDebugEnabled)
                            {
                                _log.DebugFormat("SAGA: {0} Ignoring Existing {1} for {2}", typeof(TSaga).ToFriendlyName(),
                                                 sagaId,
                                                 typeof(TMessage).ToFriendlyName());
                            }
                        }
                    }

                    if (transaction.IsActive)
                    {
                        transaction.Commit();
                    }
                }
        }
Exemplo n.º 10
0
        public IEnumerable <Action <IConsumeContext <TMessage> > > GetSaga <TMessage>(IConsumeContext <TMessage> context, Guid sagaId,
                                                                                      InstanceHandlerSelector <TSaga, TMessage>
                                                                                      selector, ISagaPolicy <TSaga, TMessage> policy)
            where TMessage : class
        {
            bool needToLeaveSagas = true;

            Monitor.Enter(_sagas);
            try
            {
                TSaga instance = _sagas[sagaId];

                if (instance == null)
                {
                    if (policy.CanCreateInstance(context))
                    {
                        instance = policy.CreateInstance(context, sagaId);
                        _sagas.Add(instance);

                        lock (instance)
                        {
                            Monitor.Exit(_sagas);
                            needToLeaveSagas = false;

                            yield return(x =>
                            {
                                if (_log.IsDebugEnabled)
                                {
                                    _log.DebugFormat("SAGA: {0} Creating New {1} for {2}", typeof(TSaga).ToFriendlyName(), sagaId,
                                                     typeof(TMessage).ToFriendlyName());
                                }

                                try
                                {
                                    foreach (var callback in selector(instance, x))
                                    {
                                        callback(x);
                                    }

                                    if (policy.CanRemoveInstance(instance))
                                    {
                                        _sagas.Remove(instance);
                                    }
                                }
                                catch (Exception ex)
                                {
                                    var sex = new SagaException("Create Saga Instance Exception", typeof(TSaga), typeof(TMessage), sagaId, ex);
                                    if (_log.IsErrorEnabled)
                                    {
                                        _log.Error(sex);
                                    }

                                    throw sex;
                                }
                            });
                        }
                    }
                    else
                    {
                        if (_log.IsDebugEnabled)
                        {
                            _log.DebugFormat("SAGA: {0} Ignoring Missing {1} for {2}", typeof(TSaga).ToFriendlyName(), sagaId,
                                             typeof(TMessage).ToFriendlyName());
                        }
                    }
                }
                else
                {
                    if (policy.CanUseExistingInstance(context))
                    {
                        Monitor.Exit(_sagas);
                        needToLeaveSagas = false;
                        lock (instance)
                        {
                            yield return(x =>
                            {
                                if (_log.IsDebugEnabled)
                                {
                                    _log.DebugFormat("SAGA: {0} Using Existing {1} for {2}", typeof(TSaga).ToFriendlyName(), sagaId,
                                                     typeof(TMessage).ToFriendlyName());
                                }

                                try
                                {
                                    foreach (var callback in selector(instance, x))
                                    {
                                        callback(x);
                                    }

                                    if (policy.CanRemoveInstance(instance))
                                    {
                                        _sagas.Remove(instance);
                                    }
                                }
                                catch (Exception ex)
                                {
                                    var sex = new SagaException("Existing Saga Instance Exception", typeof(TSaga), typeof(TMessage), sagaId, ex);
                                    if (_log.IsErrorEnabled)
                                    {
                                        _log.Error(sex);
                                    }

                                    throw sex;
                                }
                            });
                        }
                    }
                    else
                    {
                        if (_log.IsDebugEnabled)
                        {
                            _log.DebugFormat("SAGA: {0} Ignoring Existing {1} for {2}", typeof(TSaga).ToFriendlyName(), sagaId,
                                             typeof(TMessage).ToFriendlyName());
                        }
                    }
                }
            }
            finally
            {
                if (needToLeaveSagas)
                {
                    Monitor.Exit(_sagas);
                }
            }
        }
Exemplo n.º 11
0
        public IEnumerable <Action <IConsumeContext <TMessage> > > GetSaga <TMessage>(
            IConsumeContext <TMessage> context,
            Guid sagaId,
            InstanceHandlerSelector <TSaga, TMessage> selector,
            ISagaPolicy <TSaga, TMessage> policy) where TMessage : class
        {
            using (var session = this.documentStore.OpenSession())
            {
                session.Advanced.UseOptimisticConcurrency = true;

                var instance = session.Load <TSaga>(sagaId);

                if (instance == null)
                {
                    if (policy.CanCreateInstance(context))
                    {
                        yield return(x =>
                        {
                            try
                            {
                                instance = policy.CreateInstance(x, sagaId);

                                foreach (var callback in selector(instance, x))
                                {
                                    callback(x);
                                }

                                if (policy.CanRemoveInstance(instance))
                                {
                                    return;
                                }

                                session.Store(instance);
                                session.SaveChanges();
                            }
                            catch (Exception ex)
                            {
                                var sex = new SagaException(
                                    "Create Saga Instance Exception",
                                    typeof(TSaga),
                                    typeof(TMessage),
                                    sagaId,
                                    ex);

                                throw sex;
                            }
                        });
                    }
                }
                else
                {
                    if (policy.CanUseExistingInstance(context))
                    {
                        yield return(x =>
                        {
                            try
                            {
                                const int NbtriesMax = 5;

                                foreach (var callback in selector(instance, x))
                                {
                                    callback(x);
                                }

                                if (policy.CanRemoveInstance(instance))
                                {
                                    session.Delete(instance);
                                }

                                try
                                {
                                    session.SaveChanges();
                                }
                                catch (ConcurrencyException)
                                {
                                    if (x.RetryCount <= NbtriesMax)
                                    {
                                        x.RetryLater();
                                    }
                                    else
                                    {
                                        throw;
                                    }
                                }
                            }
                            catch (Exception ex)
                            {
                                var sex = new SagaException(
                                    "Existing Saga Instance Exception",
                                    typeof(TSaga),
                                    typeof(TMessage),
                                    sagaId,
                                    ex);

                                throw sex;
                            }
                        });
                    }
                }
            }
        }
        public IEnumerable <Action <IConsumeContext <TMessage> > > GetSaga <TMessage>(IConsumeContext <TMessage> context, Guid sagaId,
                                                                                      InstanceHandlerSelector <TSaga, TMessage> selector,
                                                                                      ISagaPolicy <TSaga, TMessage> policy) where TMessage : class
        {
            using (var db = dbProvider.Open())
                using (var transaction = db.BeginTransaction())
                {
                    TSaga instance = db.Get <TSaga>(sagaId, transaction);
                    Console.WriteLine("Got instance: {0}", instance == null ? "no instance" : instance.ToString());
                    if (instance == null)
                    {
                        if (policy.CanCreateInstance(context))
                        {
                            yield return(x =>
                            {
                                if (_log.IsDebugEnabled)
                                {
                                    _log.DebugFormat("SAGA: {0} Creating New {1} for {2}", typeof(TSaga).ToFriendlyName(), sagaId,
                                                     typeof(TMessage).ToFriendlyName());
                                }

                                try
                                {
                                    instance = policy.CreateInstance(x, sagaId);

                                    foreach (var callback in selector(instance, x))
                                    {
                                        callback(x);
                                    }

                                    if (!policy.CanRemoveInstance(instance))
                                    {
                                        try
                                        {
                                            db.Insert(instance, transaction);
                                        }
                                        catch (Exception)
                                        {
                                            // if insert fails update
                                            db.Update(instance, transaction);
                                        }
                                    }
                                }
                                catch (Exception ex)
                                {
                                    var sex = new SagaException("Create Saga Instance Exception", typeof(TSaga), typeof(TMessage), sagaId, ex);
                                    if (_log.IsErrorEnabled)
                                    {
                                        _log.Error(sex);
                                    }
                                    //if(transaction.IsActive) - Transaction is always active
                                    transaction.Rollback();

                                    throw sex;
                                }
                            });
                        }
                        else
                        {
                            if (_log.IsDebugEnabled)
                            {
                                _log.DebugFormat("SAGA: {0} Ignoring Missing {1} for {2}", typeof(TSaga).ToFriendlyName(), sagaId,
                                                 typeof(TMessage).ToFriendlyName());
                            }
                        }
                    }
                    else
                    {
                        Console.WriteLine("Have existing instance " + instance.ToString());
                        if (policy.CanUseExistingInstance(context))
                        {
                            yield return(x =>
                            {
                                if (_log.IsDebugEnabled)
                                {
                                    _log.DebugFormat("SAGA: {0} Using Existing {1} for {2}", typeof(TSaga).ToFriendlyName(), sagaId,
                                                     typeof(TMessage).ToFriendlyName());
                                }

                                try
                                {
                                    foreach (var callback in selector(instance, x))
                                    {
                                        callback(x);
                                    }

                                    if (policy.CanRemoveInstance(instance))
                                    {
                                        db.Delete(instance, transaction);
                                    }
                                    else
                                    {
                                        db.Update(instance, transaction);
                                    }
                                }
                                catch (Exception ex)
                                {
                                    var sex = new SagaException("Existing Saga Instance Exception", typeof(TSaga), typeof(TMessage), sagaId, ex);
                                    if (_log.IsErrorEnabled)
                                    {
                                        _log.Error(sex);
                                    }
                                    //if(transaction.IsActive) - Transaction is always active
                                    transaction.Rollback();

                                    throw sex;
                                }
                            });
                        }
                        else
                        {
                            if (_log.IsDebugEnabled)
                            {
                                _log.DebugFormat("SAGA: {0} Ignoring Existing {1} for {2}", typeof(TSaga).ToFriendlyName(), sagaId,
                                                 typeof(TMessage).ToFriendlyName());
                            }
                        }
                    }
                    transaction.Commit();
                }
        }
Exemplo n.º 13
0
        public IEnumerable <Action <IConsumeContext <TMessage> > > GetSaga <TMessage>(
            IConsumeContext <TMessage> context,
            Guid instanceId,
            InstanceHandlerSelector <TInstance, TMessage> selector,
            ISagaPolicy <TInstance, TMessage> policy) where TMessage : class
        {
            ////using (var transaction = new TransactionScope(TransactionScopeOption.RequiresNew))
            ////TODO: Looks like Custom json deserialization is not performed when GetDocument is executed
            ////var getResult = bucket.GetDocument<TInstance>(instanceId.ToString());
            ////if (!getResult.Success)
            ////{
            ////    var sagaException = new SagaException(
            ////        getResult.Message,
            ////        typeof(TInstance),
            ////        typeof(TMessage),
            ////        instanceId,
            ////        getResult.Exception);

            ////    this.log.Error(sagaException);
            ////    throw sagaException;
            ////}
            ////else if (
            ////    getResult.Document != null
            ////    && getResult.Document.Content != null)
            ////{
            ////    instance = getResult.Document.Content;
            ////}

            var instance = this
                           .Where(s => s.CorrelationId.Equals(instanceId))
                           .FirstOrDefault();

            if (instance == null)
            {
                if (policy.CanCreateInstance(context))
                {
                    yield return(action =>
                    {
                        this.log.DebugFormat(
                            "{0} Creating New instance {1} for {2}",
                            typeof(TInstance).ToFriendlyName(),
                            instanceId,
                            typeof(TMessage).ToFriendlyName());

                        try
                        {
                            instance = policy.CreateInstance(action, instanceId);

                            foreach (var callback in selector(instance, action))
                            {
                                callback(action);
                            }

                            if (!policy.CanRemoveInstance(instance))
                            {
                                this.RetrieveAndProcessResult(
                                    () => this.bucket.Insert(instanceId.ToString(), instance),
                                    result => { });
                            }
                        }
                        catch (Exception exception)
                        {
                            var sagaException = new SagaException(
                                "Create Saga Instance Exception",
                                typeof(TInstance),
                                typeof(TMessage),
                                instanceId,
                                exception);

                            this.log.Error(sagaException);
                            throw sagaException;
                        }
                    });
                }
                else
                {
                    this.log.DebugFormat(
                        "{0} Ignoring Missing instance {1} for {2}",
                        typeof(TInstance).ToFriendlyName(),
                        instanceId,
                        typeof(TMessage).ToFriendlyName());
                }
            }
            else
            {
                if (policy.CanUseExistingInstance(context))
                {
                    yield return(action =>
                    {
                        this.log.DebugFormat(
                            "{0} Using Existing instance {1} for {2}",
                            typeof(TInstance).ToFriendlyName(),
                            instanceId,
                            typeof(TMessage).ToFriendlyName());

                        try
                        {
                            foreach (var callback in selector(instance, action))
                            {
                                callback(action);
                            }

                            if (policy.CanRemoveInstance(instance))
                            {
                                this.RetrieveAndProcessResult(
                                    () => this.bucket.Remove(instanceId.ToString()),
                                    result => { });
                            }
                            else
                            {
                                this.RetrieveAndProcessResult(
                                    () => this.bucket.Replace(instanceId.ToString(), instance),
                                    result => { });
                            }
                        }
                        catch (Exception exception)
                        {
                            var sagaException = new SagaException(
                                "Existing Saga Instance Exception",
                                typeof(TInstance),
                                typeof(TMessage),
                                instanceId,
                                exception);

                            this.log.Error(sagaException);
                            throw sagaException;
                        }
                    });
                }
                else
                {
                    this.log.DebugFormat(
                        "{0} Ignoring Existing instance {1} for {2}",
                        typeof(TInstance).ToFriendlyName(),
                        instanceId,
                        typeof(TMessage).ToFriendlyName());
                }
            }
        }