Example #1
0
        private static string SafeGetParameter(QueuedJobDto nextJob, String parameter)
        {
            if (nextJob.Parameters.ContainsKey(parameter))
            {
                return(nextJob.Parameters[parameter]);
            }

            return(String.Empty);
        }
Example #2
0
        private static PollerJobParameters ExtractJobParameters(QueuedJobDto nextJob)
        {
            PollerJobParameters parameters = new PollerJobParameters();

            parameters.FileExtension       = SafeGetParameter(nextJob, JobKeys.FileExtension);
            parameters.FileName            = SafeGetParameter(nextJob, JobKeys.FileName);
            parameters.InputDocumentFormat = new DocumentFormat(SafeGetParameter(nextJob, JobKeys.Format));
            parameters.JobId    = nextJob.Id;
            parameters.TenantId = SafeGetParameter(nextJob, JobKeys.TenantId);
            parameters.All      = nextJob.Parameters;
            return(parameters);
        }
Example #3
0
 private QueuedJobDto DsGetNextJob()
 {
     try
     {
         QueuedJobDto nextJob = null;
         string       pollerResult;
         using (WebClientEx client = new WebClientEx())
         {
             //TODO: use round robin if a document store is down.
             var firstUrl = _dsEndpoints.First();
             var payload  = JsonConvert.SerializeObject(new
             {
                 QueueName = this.QueueName,
                 Identity  = this._identity,
                 Handle    = this._handle,
             });
             Logger.DebugFormat("Polling url: {0} with payload {1}", firstUrl, payload);
             client.Headers[HttpRequestHeader.ContentType] = "application/json";
             pollerResult = client.UploadString(firstUrl.GetNextJobUrl, payload);
             Logger.DebugFormat("GetNextJobResult: {0}", pollerResult);
         }
         if (!pollerResult.Equals("null", StringComparison.OrdinalIgnoreCase))
         {
             nextJob = JsonConvert.DeserializeObject <QueuedJobDto>(pollerResult, _settings);
         }
         _lastGoodCommunication = DateTime.Now;
         return(nextJob);
     }
     catch (Exception ex)
     {
         if (DateTime.UtcNow.AddMinutes(-15) > _lastCommunicationError)
         {
             //new error in 15 minutes, we need to log
             Logger.ErrorFormat(ex, "Unable to contact Document Store at address: {0}", _dsEndpoints.First());
             _lastCommunicationError = DateTime.UtcNow;
         }
         else
         {
             Logger.InfoFormat("Document store cannot be reached, down since {0}", _lastGoodCommunication);
         }
         return(null);
     }
 }
Example #4
0
        private void ExecuteJobCore()
        {
            do
            {
                //if half of the task thread finished working, we should end all the pool and restart
                if (ThreadNumber > 2 && _numOfPollerTaskActive < (ThreadNumber / 2))
                {
                    //This can happen because jobs are generated not in block, if we have ex 6 threads
                    //base jobs started 6 tasks, then if in a moment only one task remain only one task remain active
                    //then if the queue manager queue 100 jobs, we have only one thread active. This condition
                    //stops the poll if half of the threads are active, so we need to restart polling with all the tasks.
                    return;
                }
                String       workingFolder = null;
                QueuedJobDto nextJob       = DsGetNextJob();
                if (nextJob == null)
                {
                    System.Threading.Interlocked.Decrement(ref _numOfPollerTaskActive);
                    return;
                }
                Logger.ThreadProperties["job-id"] = nextJob.Id;
                var baseParameters = ExtractJobParameters(nextJob);
                //remember to enter the right tenant.
                workingFolder = Path.Combine(
                    JobsHostConfiguration.GetWorkingFolder(baseParameters.TenantId, GetType().Name),
                    baseParameters.JobId
                    );
                if (Directory.Exists(workingFolder))
                {
                    Directory.Delete(workingFolder, true);
                }

                Directory.CreateDirectory(workingFolder);
                try
                {
                    var task   = OnPolling(baseParameters, workingFolder);
                    var result = task.Result;
                    if (result.Result)
                    {
                        Logger.DebugFormat("Successfully executed Job: {0}", nextJob.Id);
                    }
                    else
                    {
                        Logger.ErrorFormat("Job {0} completed with errors: {1} with result", nextJob.Id, result.ErrorMessage);
                    }

                    //The execution if failed can be posticipated to future time, probably because the job can retry after a certain
                    //period of time.
                    if (!result.Posticipate)
                    {
                        DsSetJobExecuted(QueueName, nextJob.Id, result.ErrorMessage, result.ParametersToModify);
                    }
                    else
                    {
                        DsReQueueJob(QueueName, nextJob.Id, result.ErrorMessage, result.PosticipateExecutionTimestamp, result.ParametersToModify);
                    }
                }
                catch (AggregateException aex)
                {
                    Logger.ErrorFormat(aex, "Error executing queued job {0} on tenant {1} - {2}",
                                       nextJob.Id,
                                       nextJob.Parameters[JobKeys.TenantId],
                                       aex?.InnerExceptions?[0]?.Message);
                    StringBuilder aggregateMessage = new StringBuilder();
                    aggregateMessage.Append(aex.Message);
                    foreach (var ex in aex.InnerExceptions)
                    {
                        var errorMessage = String.Format("Inner error queued job {0} queue {1}: {2}", nextJob.Id, this.QueueName, ex.Message);
                        LogExceptionAndAllInnerExceptions(ex, errorMessage);
                        aggregateMessage.Append(errorMessage);
                    }
                    DsSetJobExecuted(QueueName, nextJob.Id, aggregateMessage.ToString(), null);
                }
                catch (Exception ex)
                {
                    var errorMessage = String.Format("Error executing queued job {0} on tenant {1}", nextJob.Id, nextJob.Parameters[JobKeys.TenantId]);
                    LogExceptionAndAllInnerExceptions(ex, errorMessage);
                    DsSetJobExecuted(QueueName, nextJob.Id, ex.Message, null);
                }
                finally
                {
                    DeleteWorkingFolder(workingFolder);
                    Logger.ThreadProperties["job-id"] = null;
                }
            } while (true); //Exit is in the internal loop
        }