コード例 #1
0
        public static ICustomOperationSpanBuilder BeginConsumerCustomOperationSpan(this ITracer tracer, string operationName)
        {
            var spanBuilder = tracer.BeginCustomOperationSpan(operationName);

            spanBuilder.SetOperationStatus(null, WellKnownStatuses.Success);
            spanBuilder.SetAnnotation(WellKnownAnnotations.Common.Component, "Hercules.Consumers");
            return(spanBuilder);
        }
コード例 #2
0
        private async Task ExecutePayloadAsync(DateTimeOffset executionTime, IScheduler scheduler, CancellationToken token)
        {
            if (token.IsCancellationRequested)
            {
                return;
            }

            var nextExecution = GetNextExecutionTime(executionTime).time;

            var timeBudget = nextExecution.HasValue
                ? TimeBudget.StartNew(TimeSpanArithmetics.Max(TimeSpan.Zero, nextExecution.Value - executionTime))
                : TimeBudget.Infinite;

            var context = new ScheduledActionContext(executionTime, timeBudget, scheduler, token);

            if (!(scheduler is PeriodicalWithConstantPauseScheduler))
            {
                log.Info("Executing with time budget = {TimeBudget}.", timeBudget.Total.ToPrettyString());
            }
            else
            {
                log.Info("Executing..");
            }

            async Task ExecutePayload()
            {
                monitor.OnIterationStarted();
                var span = tracer.BeginCustomOperationSpan(action.Name);

                try
                {
                    var watch = Stopwatch.StartNew();

                    await action.Payload(context);

                    watch.Stop();

                    log.Info(
                        "Executed in {ExecutionTime}.",
                        new
                    {
                        ExecutionTime   = watch.Elapsed.ToPrettyString(),
                        ExecutionTimeMs = watch.Elapsed.TotalMilliseconds
                    });

                    if (watch.Elapsed > timeBudget.Total && !(scheduler is PeriodicalWithConstantPauseScheduler))
                    {
                        log.Warn("Execution did not fit into the time budget before the next planned execution.");
                    }

                    action.Scheduler.OnSuccessfulIteration(scheduler);

                    span.SetOperationStatus(null, WellKnownStatuses.Success);
                    monitor.OnIterationSucceeded();
                }
                catch (Exception error)
                {
                    action.Scheduler.OnFailedIteration(scheduler, error);

                    span.SetOperationStatus(null, WellKnownStatuses.Error);
                    monitor.OnIterationFailed(error);

                    if (action.Options.CrashOnPayloadException || error is OperationCanceledException)
                    {
                        throw;
                    }

                    log.Error(error, "Scheduled action threw an exception.");
                }
                finally
                {
                    span.Dispose();
                    monitor.OnIterationCompleted();
                }
            }

            var payloadTask = action.Options.PreferSeparateThread
                ? Task.Factory.StartNew(ExecutePayload, TaskCreationOptions.LongRunning)
                : Task.Run(ExecutePayload);

            if (action.Options.AllowOverlappingExecution)
            {
                return;
            }

            await payloadTask;
        }