/// <inheritdoc />
 public async Task <IJobQueueOutputMessage> SendAsync(IScheduledJob job, DateTimeOffset scheduledTime, Expression <Action <IReceivedMessage <MessageExpression>, IWorkerNotification> > method, bool rawExpression = false)
 {
     using (IScope scope = _tracer.BuildSpan("SendJobAsync").StartActive(finishSpanOnDispose: true))
     {
         scope.Span.SetTag("JobName", job.Name);
         return(await _handler.SendAsync(job, scheduledTime, method, rawExpression));
     }
 }
示例#2
0
        internal async Task RunPendingEventAsync(PendingEvent ev)
        {
            var eventTime     = ev.ScheduledTime;
            var execLockTaken = false;

            try
            {
                lock (_scheduleLock)
                {
                    if (ev.RunId != _runId)
                    {
                        return;
                    }

                    // take execution lock
                    execLockTaken = Interlocked.CompareExchange(ref _execLocked, 1, 0) == 0;
                    if (execLockTaken)
                    {
                        PrevEvent = eventTime; // set this here while we're still in the schedule lock
                    }
                }

                if (execLockTaken)
                {
                    try
                    {
#if NETFULL
                        var result = _expressionToRun != null ? await _queue.SendAsync(this, eventTime, _expressionToRun).ConfigureAwait(false) : await _queue.SendAsync(this, eventTime, _actionToRun, RawExpression).ConfigureAwait(false);
#else
                        var result = await _queue.SendAsync(this, eventTime, _actionToRun, RawExpression).ConfigureAwait(false);
#endif
                        if (result.Status == JobQueuedStatus.Success || result.Status == JobQueuedStatus.RequeuedDueToErrorStatus)
                        {
                            RaiseEnQueue(result);
                            _queue.Logger.LogDebug($"job {this} queued");
                        }
                        else if (result.Status == JobQueuedStatus.AlreadyQueuedWaiting ||
                                 result.Status == JobQueuedStatus.AlreadyQueuedProcessing ||
                                 result.Status == JobQueuedStatus.AlreadyProcessed)
                        {
                            _queue.Logger.LogWarning($"Failed to enqueue job {this}, the status is {result.Status}");
                            RaiseNonFatalFailureEnQueue(result);
                        }
                        else if (result.SendingException != null)
                        {
                            _queue.Logger.LogError($"An error has occurred adding job {this} into the queue{System.Environment.NewLine}{result.SendingException}");
                            RaiseException(result.SendingException);
                        }
                    }
                    catch (Exception ex)
                    {
                        _queue.Logger.LogError($"A fatal error has occurred trying to add job {this} into the queue{System.Environment.NewLine}{ex}");
                        RaiseException(ex);
                    }
                }
            }
            finally
            {
                if (execLockTaken)
                {
                    _execLocked = 0; // release exec lock
                }
            }

            // figure out the next time to run the schedule
            lock (_scheduleLock)
            {
                if (ev.RunId != _runId)
                {
                    return;
                }

                try
                {
                    var next = Schedule.Next();
                    if (next <= eventTime)
                    {
                        next = Schedule.Next(eventTime);
                    }

                    NextEvent = next;
                    QueueNextEvent();
                }
                catch (Exception ex)
                {
                    _runId++;
                    IsScheduleRunning = false;
                    RaiseException(new DotNetWorkQueueException("Schedule has been terminated because the next valid time could not be found.", ex));
                }
            }
        }