Exemple #1
0
 public void IterationCleanup()
 {
     if (useLargeData)
     {
         largePersistence?.Clear();
         largePersistence?.Dispose();
     }
     else
     {
         smallPersistence?.Clear();
         smallPersistence?.Dispose();
     }
 }
Exemple #2
0
        public override async Task Invoke(IIncomingLogicalMessageContext context, Func <Task> next)
        {
            MessagesConcurrent.Increment();

            // Only SEND messages deserve a UnitOfWork
            if (context.MessageHeaders[Headers.MessageIntent] != MessageIntentEnum.Send.ToString())
            {
                await next().ConfigureAwait(false);

                return;
            }


            Logger.Write(LogLevel.Info,
                         () => $"Starting UOW for message {context.MessageId} type {context.Message.MessageType.FullName}");
            var uows = new Stack <IApplicationUnitOfWork>();

            try
            {
                MessagesMeter.Mark();
                using (MessagesTimer.NewContext())
                {
                    using (BeginTimer.NewContext())
                    {
                        var listOfUows = context.Builder.BuildAll <IApplicationUnitOfWork>();
                        // Trick to put ILastApplicationUnitOfWork at the bottom of the stack to be uow.End'd last
                        foreach (var uow in listOfUows.Where(x => x is ILastApplicationUnitOfWork).Concat(listOfUows.Where(x => !(x is ILastApplicationUnitOfWork))))
                        {
                            uow.Builder = context.Builder;

                            int retries;
                            if (!context.Extensions.TryGet(Defaults.Retries, out retries))
                            {
                                retries = 0;
                            }
                            uow.Retries = retries;

                            var savedBag =
                                await _persistence.Remove(context.MessageId, uow.GetType()).ConfigureAwait(false);

                            uow.Bag = savedBag ?? new ContextBag();
                            Logger.Write(LogLevel.Debug, () => $"Running UOW.Begin for message {context.MessageId} on {uow.GetType().FullName}");
                            await uow.Begin().ConfigureAwait(false);

                            uows.Push(uow);
                        }
                    }

                    using (ProcessTimer.NewContext())
                    {
                        DelayedMessage[] delayed;
                        // Special case for delayed messages read from delayed stream
                        if (context.Headers.ContainsKey(Defaults.BulkHeader) && context.Extensions.TryGet(Defaults.BulkHeader, out delayed))
                        {
                            foreach (var x in delayed)
                            {
                                // Replace all headers with the original headers to preserve CorrId etc.
                                context.Headers.Clear();
                                foreach (var header in x.Headers)
                                {
                                    context.Headers[header.Key] = header.Value;
                                }

                                context.Headers["Delayed Channel"] = x.ChannelKey;

                                context.Extensions.Set(Defaults.ChannelKey, x.ChannelKey);

                                context.UpdateMessageInstance(x.Message);
                                await next().ConfigureAwait(true);
                            }
                        }
                        else
                        {
                            await next().ConfigureAwait(false);
                        }
                    }

                    using (EndTimer.NewContext())
                    {
                        foreach (var uow in uows.PopAll())
                        {
                            Logger.Write(LogLevel.Debug, () => $"Running UOW.End for message {context.MessageId} on {uow.GetType().FullName}");

                            try
                            {
                                // ConfigureAwait true because we don't want uow.End running in parrallel
                                await uow.End().ConfigureAwait(true);
                            }
                            finally
                            {
                                await _persistence.Save(context.MessageId, uow.GetType(), uow.Bag).ConfigureAwait(true);
                            }
                        }
                    }
                    // Only clear context bags once all UOWs complete successfully
                    await _persistence.Clear(context.MessageId).ConfigureAwait(false);
                }
            }
            catch (Exception e)
            {
                Logger.Warn(
                    $"Caught exception '{e.GetType().FullName}' while executing message {context.MessageId} {context.Message.MessageType.FullName}");

                ErrorsMeter.Mark(context.Message.MessageType.FullName);
                var trailingExceptions = new List <Exception>();
                using (EndTimer.NewContext())
                {
                    foreach (var uow in uows.PopAll())
                    {
                        try
                        {
                            Logger.Write(LogLevel.Debug,
                                         () => $"Running UOW.End with exception [{e.GetType().Name}] for message {context.MessageId} on {uow.GetType().FullName}");
                            await uow.End(e).ConfigureAwait(true);
                        }
                        catch (Exception endException)
                        {
                            trailingExceptions.Add(endException);
                        }
                        await _persistence.Save(context.MessageId, uow.GetType(), uow.Bag).ConfigureAwait(true);
                    }
                }

                if (trailingExceptions.Any())
                {
                    trailingExceptions.Insert(0, e);
                    throw new System.AggregateException(trailingExceptions);
                }
                throw;
            }
            finally
            {
                MessagesConcurrent.Decrement();
            }
        }
 /// <summary>
 /// Clears all items from this structure and persistence
 /// </summary>
 public void Clear()
 {
     inMemoryItems.Clear();
     persistence.Clear();
 }