public void DisposeStopsTimingTest()
        {
            Assert.Equal(0, _timingBlock.Count);

            Task.Delay(1);

            _timerContext.Dispose();

            Assert.Equal(1, _timingBlock.Count);
        }
Ejemplo n.º 2
0
        async Task ICommandUnitOfWork.End(Exception ex)
        {
            if (ex == null)
            {
                await Commit();
            }
            else
            {
                _errorsMeter.Mark();
            }

            _commandsConcurrent.Decrement();
            _timerContext.Dispose();
        }
Ejemplo n.º 3
0
        public void Acknowledge(ResolvedEvent @event)
        {
            if (!Live)
            {
                throw new InvalidOperationException("Cannot ACK an event, subscription is dead");
            }

            Processed.Increment(Id);
            _idleContext.Dispose();
            _toAck.Add(@event);
        }
Ejemplo n.º 4
0
        protected virtual void Dispose(bool disposing)
        {
            if (_disposed)
            {
                return;
            }

            if (disposing && _ctx != null)
            {
                _ctx.Dispose();
            }

            _disposed = true;
        }
Ejemplo n.º 5
0
 public void Acknowledge(ResolvedEvent[] events)
 {
     Processed.Increment(Id);
     _idleContext.Dispose();
     _toAck.AddRange(events);
 }
 public Task DeactivatedFinallyAsync()
 {
     _deactivatingActivity?.Dispose();
     _deactivationTimer.Dispose();
     return(Task.CompletedTask);
 }
 public Task HandledEventFinallyAsync(IEvent @event)
 {
     _handlingActivity?.Dispose();
     _eventHandlingTimer.Dispose();
     return(Task.CompletedTask);
 }
Ejemplo n.º 8
0
 public void Dispose()
 {
     _counter.Decrement();
     _context.Dispose();
 }
Ejemplo n.º 9
0
 public override void OnSuccess(MethodExecutionArgs args)
 {
     _counter.Decrement();
     _context.Dispose();
     base.OnSuccess(args);
 }
Ejemplo n.º 10
0
        private static void Threaded(object state)
        {
            var param = (ThreadParam)state;

            param.Clients.SelectAsync(x => x.Connect()).Wait();

            var threadIdle = Metric.Timer("Delayed Events Idle", Unit.None, tags: "debug");
            var tasks      = new Task[param.Clients.Count()];

            TimerContext?idleContext = threadIdle.NewContext();

            while (true)
            {
                param.Token.ThrowIfCancellationRequested();

                var noEvents = true;
                for (var i = 0; i < param.Clients.Count(); i++)
                {
                    // Check if current task is complete
                    if (tasks[i] != null && !tasks[i].IsCompleted)
                    {
                        continue;
                    }

                    var client = param.Clients.ElementAt(i);
                    var events = client.Flush();

                    DelayedHandled.Update(events.Count());
                    if (!events.Any())
                    {
                        continue;
                    }

                    noEvents = false;
                    idleContext?.Dispose();
                    idleContext = null;

                    tasks[i] = Task.Run(async() =>
                    {
                        using (var ctx = DelayedExecution.NewContext())
                        {
                            // Group delayed events from by stream id and process in chunks
                            // Same stream ids should modify the same models, processing this way reduces write collisions on commit
                            await events.GroupBy(x => x.Event.EventStreamId)
                            .SelectAsync(x => ProcessEvents(param, client, x.ToArray())).ConfigureAwait(false);

                            if (ctx.Elapsed > TimeSpan.FromSeconds(5))
                            {
                                SlowLogger.Warn($"Processing {events.Count()} bulked events took {ctx.Elapsed.TotalSeconds} seconds!");
                            }
                            Logger.Write(LogLevel.Info,
                                         () => $"Processing {events.Count()} bulked events took {ctx.Elapsed.TotalMilliseconds} ms");
                        }
                    }, param.Token);
                }

                if (idleContext == null)
                {
                    idleContext = threadIdle.NewContext();
                }
                // Cheap hack to not burn cpu incase there are no events
                if (noEvents)
                {
                    Thread.Sleep(50);
                }
            }
        }
Ejemplo n.º 11
0
        private static void Threaded(object state)
        {
            var param = (ThreadParam)state;

            param.Clients.SelectAsync(x => x.Connect()).Wait();

            var threadIdle = Metric.Timer("Process Events Idle", Unit.None, tags: "debug");
            var tasks      = new Task[param.Clients.Count()];

            TimerContext?idleContext = threadIdle.NewContext();

            while (true)
            {
                param.Token.ThrowIfCancellationRequested();

                var noEvents = true;
                for (var i = 0; i < param.Clients.Count(); i++)
                {
                    // Check if current task is complete
                    if (tasks[i] != null && !tasks[i].IsCompleted)
                    {
                        continue;
                    }

                    // Ready for a new event
                    var client = param.Clients.ElementAt(i);

                    ResolvedEvent e;
                    if (!client.TryDequeue(out e))
                    {
                        continue;
                    }

                    var @event = e.Event;

                    Logger.Write(LogLevel.Debug,
                                 () => $"Processing event {@event.EventId} type {@event.EventType} stream [{@event.EventStreamId}] number {@event.EventNumber}");

                    noEvents = false;

                    idleContext?.Dispose();
                    idleContext = null;

                    Events.Mark(e.OriginalStreamId);

                    tasks[i] = Task.Run(async() =>
                    {
                        await ProcessEvent(param.MessageMeta, param.JsonSettings, @event, param.Token).ConfigureAwait(false);

                        Logger.Write(LogLevel.Debug,
                                     () => $"Scheduling acknowledge event {@event.EventId} type {@event.EventType} stream [{@event.EventStreamId}] number {@event.EventNumber}");
                        client.Acknowledge(e);
                    }, param.Token);
                }
                if (idleContext == null)
                {
                    idleContext = threadIdle.NewContext();
                }
                // Cheap hack to not burn cpu incase there are no events
                if (noEvents)
                {
                    Thread.Sleep(50);
                }
            }
        }
Ejemplo n.º 12
0
 public override void OnSuccess(MethodExecutionArgs args)
 {
     context.Dispose();
 }
Ejemplo n.º 13
0
 public Task DeactivatedAsync()
 {
     _deactivationTimer.Dispose();
     return(Task.CompletedTask);
 }
Ejemplo n.º 14
0
 public Task HandledEventAsync(IEvent @event)
 {
     _eventHandlingTimer.Dispose();
     return(Task.CompletedTask);
 }
Ejemplo n.º 15
0
        private static TracerDecoratorBuilder WithAppMetrics(this TracerDecoratorBuilder builder, IMetrics metrics, OpenTracingAppMetricsDecoratorOptions options, Action <OpenTracingAppMetricsDecoratorOptions> setupOptions)
        {
            options = options ?? throw new ArgumentNullException(nameof(options));
            setupOptions?.Invoke(options);

            if (options.SpansCountersEnabled)
            {
                var spansCounter = new CounterOptions
                {
                    Name = options.SpansCounterName
                };

                builder.OnSpanStarted((span, operationName) =>
                {
                    metrics.Measure.Counter.Increment(spansCounter, operationName);

                    if (options.DistinctOperationsCountersEnabled)
                    {
                        var distinctCounter = new CounterOptions {
                            Name = options.DistinctOperationCountersName + operationName
                        };
                        metrics.Measure.Counter.Increment(distinctCounter);
                    }
                });

                builder.OnSpanFinished((span, operationName) =>
                {
                    metrics.Measure.Counter.Decrement(spansCounter, operationName);

                    if (options.DistinctOperationsCountersEnabled)
                    {
                        var distinctCounter = new CounterOptions {
                            Name = options.DistinctOperationCountersName + operationName
                        };
                        metrics.Measure.Counter.Decrement(distinctCounter);
                    }
                });
            }

            if (options.SpansMetersEnabled)
            {
                var spansMeter = new MeterOptions
                {
                    Name = options.SpansMeterName
                };

                builder.OnSpanStarted((span, operationName) =>
                {
                    metrics.Measure.Meter.Mark(spansMeter, operationName);

                    if (options.DistinctOperationsMetersEnabled)
                    {
                        var distinctMeter = new MeterOptions {
                            Name = options.DistinctOperationMetersName + operationName
                        };
                        metrics.Measure.Meter.Mark(distinctMeter);
                    }
                });
            }

            if (options.SpansTimersEnabled)
            {
                var spansTimer = new TimerOptions
                {
                    Name         = options.SpansTimerName,
                    DurationUnit = TimeUnit.Milliseconds,
                    RateUnit     = TimeUnit.Milliseconds
                };

                builder.OnSpanStartedWithCallback((span, operationName) =>
                {
                    var timerContext = metrics.Measure.Timer.Time(spansTimer, operationName);

                    TimerContext distinctTimerContext = default(TimerContext);
                    if (options.DistinctOperationsTimersEnabled)
                    {
                        var distinctTimer = new TimerOptions
                        {
                            Name         = options.DistinctOperationTimersName + operationName,
                            DurationUnit = TimeUnit.Milliseconds,
                            RateUnit     = TimeUnit.Milliseconds
                        };
                        distinctTimerContext = metrics.Measure.Timer.Time(distinctTimer);
                    }

                    return((sp, op) =>
                    {
                        timerContext.Dispose();
                        distinctTimerContext.Dispose();
                    });
                });
            }

            return(builder);
        }
Ejemplo n.º 16
0
        private static void Threaded(object state)
        {
            var param = (ThreadParam)state;
            // A fake message that will travel through the pipeline in order to bulk process messages from the context bag
            var bulkMarker = new BulkMessage().Serialize(param.JsonSettings).AsByteArray();

            param.Clients.SelectAsync(x => x.Connect()).Wait();

            var threadIdle = Metric.Timer("Delayed Events Idle", Unit.None, tags: "debug");

            TimerContext?idleContext = threadIdle.NewContext();

            while (true)
            {
                param.Token.ThrowIfCancellationRequested();

                var noEvents = true;
                for (var i = 0; i < param.Clients.Count(); i++)
                {
                    var client = param.Clients.ElementAt(i);
                    var events = client.Flush();

                    if (!events.Any())
                    {
                        continue;
                    }

                    noEvents = false;
                    idleContext?.Dispose();
                    idleContext = null;

                    var delayed = events.Select(x => x.Event.Data.Deserialize <DelayedMessage>(param.JsonSettings)).ToArray();

                    Logger.Write(LogLevel.Info, () => $"Processing {delayed.Count()} bulk events");

                    var transportTransaction = new TransportTransaction();
                    var contextBag           = new ContextBag();
                    // Hack to get all the delayed messages to bulk invoker without NSB deserializing and processing each one
                    contextBag.Set(Defaults.BulkHeader, delayed);

                    // Need to supply EnclosedMessageTypes to trick NSB pipeline into processing our fake message
                    var messageId = Guid.NewGuid().ToString();
                    var headers   = new Dictionary <string, string>()
                    {
                        [Headers.EnclosedMessageTypes] = typeof(BulkMessage).AssemblyQualifiedName,
                        [Headers.MessageIntent]        = MessageIntentEnum.Send.ToString(),
                        [Headers.MessageId]            = messageId,
                        [Defaults.BulkHeader]          = delayed.Count().ToString(),
                    };

                    // Run bulk process on this thread
                    using (var tokenSource = new CancellationTokenSource())
                    {
                        var success = false;
                        var retry   = 0;
                        do
                        {
                            using (var ctx = DelayedExecution.NewContext())
                            {
                                try
                                {
                                    // If canceled, this will throw the number of time immediate retry requires to send the message to the error queue
                                    param.Token.ThrowIfCancellationRequested();

                                    // Don't re-use the event id for the message id
                                    var messageContext = new NServiceBus.Transport.MessageContext(messageId,
                                                                                                  headers,
                                                                                                  bulkMarker, transportTransaction, tokenSource,
                                                                                                  contextBag);
                                    Bus.OnMessage(messageContext).Wait(param.Token);

                                    Logger.Write(LogLevel.Debug,
                                                 () => $"Scheduling acknowledge of {delayed.Count()} bulk events");
                                    DelayedHandled.Update(delayed.Count());
                                    client.Acknowledge(events);
                                    success = true;
                                }
                                catch (ObjectDisposedException)
                                {
                                    // NSB transport has been disconnected
                                    break;
                                }
                                catch (Exception ex)
                                {
                                }

                                if (ctx.Elapsed > TimeSpan.FromSeconds(5))
                                {
                                    SlowLogger.Warn(
                                        $"Processing {delayed.Count()} bulked events took {ctx.Elapsed.TotalSeconds} seconds!");
                                }
                                Logger.Write(LogLevel.Info,
                                             () =>
                                             $"Processing {delayed.Count()} bulked events took {ctx.Elapsed.TotalMilliseconds} ms");
                            }
                            // Todo: use max retry setting
                        } while (!success && retry < 10);

                        if (!success)
                        {
                            // Dont run through NSB's error handler, it expects a single serialized message which
                            // is not compatible here.  Just tell EventStore to retry it
                            // Todo: ES will park messages that fail - develop something to monitor parked messages
                            client.Nack(events);
                        }
                    }
                }
                if (idleContext == null)
                {
                    idleContext = threadIdle.NewContext();
                }
                // Cheap hack to not burn cpu incase there are no events
                if (noEvents)
                {
                    Thread.Sleep(50);
                }
            }
        }