Creates an XML Linq XElement from an Exception instance.
Inheritance: System.Xml.Linq.XElement
Exemplo n.º 1
0
        internal void RunLoop()
        {
            while (true)
            {
                bool          working = false, needsRest = true;
                WorkingRecord record = null;
                IJob          job    = null;
                Exception     ex     = null;

                try
                {
                    // Find out if we're supposed to be doing work.
                    lock (this.statusLocker)
                    {
                        working = this.Status == WorkerStatus.Working;
                    }

                    if (working)
                    {
                        // Dequeue a new job to work on.
                        record = this.DequeueRecord();

                        // If a record exists, we have work to do.
                        if (record != null)
                        {
                            // Try to de-serialize a job.
                            try
                            {
                                job = JobSerializer.Deserialize(record.JobType, record.Data);
                                this.logger.Debug("Worker {0} ({1}) de-serialized a job instance for '{2}'.", this.name, this.id, record.JobType);
                            }
                            catch (Exception sx)
                            {
                                ex = sx;
                                this.logger.Warn("Worker {0} ({1}) failed to de-serialize a job instane for '{2}'.", this.name, this.id, record.JobType);
                            }

                            // If we failed to de-serialize, fail the job.
                            if (job == null)
                            {
                                HistoryRecord history = CreateHistory(record, HistoryStatus.Failed);

                                if (ex != null)
                                {
                                    history.Exception = new ExceptionXElement(ex).ToString();
                                }

                                using (IRepository repository = this.repositoryFactory.Create())
                                {
                                    using (IDbTransaction transaction = repository.BeginTransaction())
                                    {
                                        repository.DeleteWorking(record.Id.Value, transaction);
                                        history = repository.CreateHistory(history, transaction);
                                        transaction.Commit();
                                    }
                                }
                            }
                            else
                            {
                                // Update this instance's current record so we can interrupt
                                // execution if necessary.
                                lock (this.runLocker)
                                {
                                    this.currentRecord = record;
                                }

                                // Execute the job.
                                bool success = this.ExecuteJob(job, out ex);

                                // Acquire the run lock and move the job from the working
                                // state to the history state, including the execution results.
                                lock (this.runLocker)
                                {
                                    HistoryStatus status          = HistoryStatus.Succeeded;
                                    string        exceptionString = null;

                                    if (success)
                                    {
                                        this.logger.Info("Worker {0} ({1}) executed '{2}' successfully.", this.name, this.id, this.currentRecord.JobName);
                                    }
                                    else
                                    {
                                        if (ex as TimeoutException != null)
                                        {
                                            status = HistoryStatus.TimedOut;
                                            this.logger.Warn("Worker {0} ({1}) timed out '{2}'.", this.name, this.id, this.currentRecord.JobName);
                                        }
                                        else
                                        {
                                            status = HistoryStatus.Failed;

                                            if (ex != null)
                                            {
                                                exceptionString = new ExceptionXElement(ex).ToString();
                                            }

                                            this.logger.Warn("Worker {0} ({1}) encountered an exception during execution of '{2}'.", this.name, this.id, this.currentRecord.JobName);
                                        }
                                    }

                                    HistoryRecord history = CreateHistory(this.currentRecord, status);
                                    history.Exception = exceptionString;

                                    using (IRepository repository = this.repositoryFactory.Create())
                                    {
                                        using (IDbTransaction transaction = repository.BeginTransaction())
                                        {
                                            repository.DeleteWorking(this.currentRecord.Id.Value, transaction);
                                            history = repository.CreateHistory(history, transaction);

                                            // Re-try?
                                            if ((status == HistoryStatus.Failed ||
                                                 status == HistoryStatus.Interrupted ||
                                                 status == HistoryStatus.TimedOut) &&
                                                (job.Retries == 0 || job.Retries >= this.currentRecord.TryNumber))
                                            {
                                                repository.CreateQueued(CreateQueueRetry(this.currentRecord), transaction);
                                            }

                                            transaction.Commit();
                                        }
                                    }

                                    this.currentRecord = null;
                                }
                            }

                            needsRest = false;
                        }
                    }
                    else
                    {
                        break;
                    }
                }
                catch (ThreadAbortException)
                {
                    throw;
                }
                catch (Exception rx)
                {
                    this.logger.Error(rx, "Exception thrown during the run loop for worker {0} ({1}).", this.name, this.id);
                }

                if (working)
                {
                    // Take a breather real quick.
                    if (needsRest)
                    {
                        this.logger.Debug("Worker {0} ({1}) is resting before trying to de-queue another job.", this.name, this.id);
                        Thread.Sleep(this.heartbeat.Randomize());
                    }
                    else
                    {
                        this.logger.Debug("Worker {0} ({1}) will immediately try to de-queue another job.", this.name, this.id);
                    }
                }
            }
        }
Exemplo n.º 2
0
        internal void RunLoop()
        {
            while (true)
            {
                bool working = false, needsRest = true;
                WorkingRecord record = null;
                IJob job = null;
                Exception ex = null;

                try
                {
                    // Find out if we're supposed to be doing work.
                    lock (this.statusLocker)
                    {
                        working = this.Status == WorkerStatus.Working;
                    }

                    if (working)
                    {
                        // Dequeue a new job to work on.
                        record = this.DequeueRecord();

                        // If a record exists, we have work to do.
                        if (record != null)
                        {
                            // Try to de-serialize a job.
                            try
                            {
                                job = JobSerializer.Deserialize(record.JobType, record.Data);
                                this.logger.Debug("Worker {0} ({1}) de-serialized a job instance for '{2}'.", this.name, this.id, record.JobType);
                            }
                            catch (Exception sx)
                            {
                                ex = sx;
                                this.logger.Warn("Worker {0} ({1}) failed to de-serialize a job instane for '{2}'.", this.name, this.id, record.JobType);
                            }

                            // If we failed to de-serialize, fail the job.
                            if (job == null)
                            {
                                HistoryRecord history = CreateHistory(record, HistoryStatus.Failed);

                                if (ex != null)
                                {
                                    history.Exception = new ExceptionXElement(ex).ToString();
                                }

                                using (IRepository repository = this.repositoryFactory.Create())
                                {
                                    using (IDbTransaction transaction = repository.BeginTransaction())
                                    {
                                        repository.DeleteWorking(record.Id.Value, transaction);
                                        history = repository.CreateHistory(history, transaction);
                                        transaction.Commit();
                                    }
                                }
                            }
                            else
                            {
                                // Update this instance's current record so we can interrupt
                                // execution if necessary.
                                lock (this.runLocker)
                                {
                                    this.currentRecord = record;
                                }

                                // Execute the job.
                                bool success = this.ExecuteJob(job, out ex);

                                // Acquire the run lock and move the job from the working
                                // state to the history state, including the execution results.
                                lock (this.runLocker)
                                {
                                    HistoryStatus status = HistoryStatus.Succeeded;
                                    string exceptionString = null;

                                    if (success)
                                    {
                                        this.logger.Info("Worker {0} ({1}) executed '{2}' successfully.", this.name, this.id, this.currentRecord.JobName);
                                    }
                                    else
                                    {
                                        if (ex as TimeoutException != null)
                                        {
                                            status = HistoryStatus.TimedOut;
                                            this.logger.Warn("Worker {0} ({1}) timed out '{2}'.", this.name, this.id, this.currentRecord.JobName);
                                        }
                                        else
                                        {
                                            status = HistoryStatus.Failed;

                                            if (ex != null)
                                            {
                                                exceptionString = new ExceptionXElement(ex).ToString();
                                            }

                                            this.logger.Warn("Worker {0} ({1}) encountered an exception during execution of '{2}'.", this.name, this.id, this.currentRecord.JobName);
                                        }
                                    }

                                    HistoryRecord history = CreateHistory(this.currentRecord, status);
                                    history.Exception = exceptionString;

                                    using (IRepository repository = this.repositoryFactory.Create())
                                    {
                                        using (IDbTransaction transaction = repository.BeginTransaction())
                                        {
                                            repository.DeleteWorking(this.currentRecord.Id.Value, transaction);
                                            history = repository.CreateHistory(history, transaction);

                                            // Re-try?
                                            if ((status == HistoryStatus.Failed
                                                || status == HistoryStatus.Interrupted
                                                || status == HistoryStatus.TimedOut)
                                                && (job.Retries == 0 || job.Retries >= this.currentRecord.TryNumber))
                                            {
                                                repository.CreateQueued(CreateQueueRetry(this.currentRecord), transaction);
                                            }

                                            transaction.Commit();
                                        }
                                    }

                                    this.currentRecord = null;
                                }
                            }

                            needsRest = false;
                        }
                    }
                    else
                    {
                        break;
                    }
                }
                catch (ThreadAbortException)
                {
                    throw;
                }
                catch (Exception rx)
                {
                    this.logger.Error(rx, "Exception thrown during the run loop for worker {0} ({1}).", this.name, this.id);
                }

                if (working)
                {
                    // Take a breather real quick.
                    if (needsRest)
                    {
                        this.logger.Debug("Worker {0} ({1}) is resting before trying to de-queue another job.", this.name, this.id);
                        Thread.Sleep(this.heartbeat.Randomize());
                    }
                    else
                    {
                        this.logger.Debug("Worker {0} ({1}) will immediately try to de-queue another job.", this.name, this.id);
                    }
                }
            }
        }