Exemplo n.º 1
0
        public object Run(PerformContext context, IJobPerformer performer)
        {
            if (context == null) throw new ArgumentNullException("context");
            if (performer == null) throw new ArgumentNullException("performer");

            var filterInfo = GetFilters(context.Job);

            try
            {
                return PerformJobWithFilters(context, performer, filterInfo.ServerFilters);
            }
            catch (OperationCanceledException)
            {
                throw;
            }
            catch (Exception ex)
            {
                var exceptionContext = new ServerExceptionContext(context, ex);
                InvokeServerExceptionFilters(exceptionContext, filterInfo.ServerExceptionFilters);

                if (!exceptionContext.ExceptionHandled)
                {
                    throw;
                }
            }

            return null;
        }
 internal ServerExceptionContext(
     PerformContext context, 
     Exception exception)
     : base(context)
 {
     Exception = exception;
 }
Exemplo n.º 3
0
        public object Perform(PerformContext context)
        {
            if (context == null) throw new ArgumentNullException(nameof(context));

            var filterInfo = GetFilters(context.BackgroundJob.Job);

            try
            {
                return PerformJobWithFilters(context, filterInfo.ServerFilters);
            }
            catch (JobAbortedException)
            {
                throw;
            }
            catch (Exception ex)
            {
                // TODO: Catch only JobPerformanceException, and pass InnerException to filters in 2.0.0.

                if (ex is OperationCanceledException && context.CancellationToken.ShutdownToken.IsCancellationRequested)
                {
                    throw;
                }

                var exceptionContext = new ServerExceptionContext(context, ex);
                InvokeServerExceptionFilters(exceptionContext, filterInfo.ServerExceptionFilters);

                if (!exceptionContext.ExceptionHandled)
                {
                    throw;
                }
            }

            return null;
        }
Exemplo n.º 4
0
 internal PerformedContext(
     PerformContext context, 
     bool canceled, 
     Exception exception)
     : base(context)
 {
     Canceled = canceled;
     Exception = exception;
 }
Exemplo n.º 5
0
 public void CopyCtor_CopiesAllPropertyValues()
 {
     var context = CreateContext();
     var contextCopy = new PerformContext(context);
     
     Assert.Same(context.Items, contextCopy.Items);
     Assert.Same(context.Connection, contextCopy.Connection);
     Assert.Same(context.BackgroundJob, contextCopy.BackgroundJob);
     Assert.Same(context.CancellationToken, contextCopy.CancellationToken);
 }
Exemplo n.º 6
0
 internal PerformedContext(
     PerformContext context,
     object result,
     bool canceled,
     Exception exception)
     : base(context)
 {
     Result = result;
     Canceled = canceled;
     Exception = exception;
 }
        public PreserveCultureAttributeFacts()
        {
            _connection = new Mock<IStorageConnection>();
            var job = Job.FromExpression(() => Sample());
            var state = new Mock<IState>();

            var createContext = new CreateContext(
                _connection.Object, job, state.Object);
            _creatingContext = new CreatingContext(createContext);

            var workerContext = new WorkerContextMock();

            var performContext = new PerformContext(
                workerContext.Object, _connection.Object, JobId, job, DateTime.UtcNow, new Mock<IJobExecutionContext>().Object);
            _performingContext = new PerformingContext(performContext);
            _performedContext = new PerformedContext(performContext, null, false, null);
        }
Exemplo n.º 8
0
        private static void PerformJobWithFilters(
            PerformContext context,
            IJobPerformStrategy strategy,
            IEnumerable<IServerFilter> filters)
        {
            var preContext = new PerformingContext(context);
            Func<PerformedContext> continuation = () =>
            {
                strategy.Perform();
                return new PerformedContext(context, false, null);
            };

            var thunk = filters.Reverse().Aggregate(continuation,
                (next, filter) => () => InvokePerformFilter(filter, preContext, next));
            
            thunk();
        }
        public PreserveCultureAttributeFacts()
        {
            _connection = new Mock<IStorageConnection>();

            var storage = new Mock<JobStorage>();
            var backgroundJob = new BackgroundJobMock { Id = JobId };
            var state = new Mock<IState>();

            var createContext = new CreateContext(
                storage.Object, _connection.Object, backgroundJob.Job, state.Object);
            _creatingContext = new CreatingContext(createContext);

            var performContext = new PerformContext(
                _connection.Object, backgroundJob.Object, new Mock<IJobCancellationToken>().Object);
            _performingContext = new PerformingContext(performContext);
            _performedContext = new PerformedContext(performContext, null, false, null);
        }
Exemplo n.º 10
0
        public void Run(PerformContext context, IJobPerformStrategy strategy)
        {
            var filterInfo = GetFilters(context.MethodData);

            try
            {
                PerformJobWithFilters(context, strategy, filterInfo.ServerFilters);
            }
            catch (Exception ex)
            {
                var exceptionContext = new ServerExceptionContext(context, ex);
                InvokeServerExceptionFilters(exceptionContext, filterInfo.ServerExceptionFilters);

                if (!exceptionContext.ExceptionHandled)
                {
                    throw;
                }
            }
        }
Exemplo n.º 11
0
        private static object PerformJobWithFilters(
            PerformContext context,
            IJobPerformer performer,
            IEnumerable<IServerFilter> filters)
        {
            object result = null;

            var preContext = new PerformingContext(context);
            Func<PerformedContext> continuation = () =>
            {
                result = performer.Perform(context.Activator, context.CancellationToken);
                return new PerformedContext(context, result, false, null);
            };

            var thunk = filters.Reverse().Aggregate(continuation,
                (next, filter) => () => InvokePerformFilter(filter, preContext, next));
            
            thunk();

            return result;
        }
Exemplo n.º 12
0
        public object Perform(PerformContext context)
        {
            using (var scope = _activator.BeginScope())
            {
                object instance = null;

                if (!context.BackgroundJob.Job.Method.IsStatic)
                {
                    instance = scope.Resolve(context.BackgroundJob.Job.Type);

                    if (instance == null)
                    {
                        throw new InvalidOperationException(
                            String.Format("JobActivator returned NULL instance of the '{0}' type.", context.BackgroundJob.Job.Type));
                    }
                }

                var arguments = SubstituteArguments(context);
                var result = InvokeMethod(context.BackgroundJob.Job.Method, instance, arguments);

                return result;
            }
        }
Exemplo n.º 13
0
 public async Task ProcessResults(PerformContext hangfireContext)
 {
     await _carlaSharepoint.ProcessResultsFolders();
 }
Exemplo n.º 14
0
        public BlogRssItem[] GetBlogPosts(PerformContext context)
        {
            var posts = new List <BlogRssItem>();

            var progressBar = context.WriteProgressBar();
            var blogs       = GetBlogs();

            foreach (var blog in blogs.WithProgress(progressBar, blogs.Length))
            {
                try
                {
                    string       raw;
                    const string userAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3393.4 Safari/537.36";
                    context.WriteLine($"Processing blog {blog.Title}");
                    // Initialize a new web client (with the encoding specified for the blog)
                    using (var wc = new WebClient())
                    {
                        wc.Headers.Add(HttpRequestHeader.UserAgent, userAgent);
                        wc.Encoding = blog.Encoding;

                        // Download the raw XML
                        raw = wc.DownloadString(blog.RssUrl);
                        raw = RemoveLeadingCharacters(raw).Replace("a10:updated", "pubDate");
                    }
                    // Parse the XML into a new instance of XElement
                    var feed = XElement.Parse(raw);

                    var channel              = feed.Element("channel");
                    var channelTitle         = channel.GetElementValue("title");
                    var channelLink          = channel.GetElementValue("link");
                    var channelDescription   = channel.GetElementValue("description");
                    var channelLastBuildDate = channel.GetElementValue("lastBuildDate");
                    var channelLangauge      = channel.GetElementValue("language");

                    var rssChannel = new BlogRssChannel
                    {
                        Id    = blog.Id,
                        Title = channelTitle,
                        Link  = channelLink
                    };

                    var items = channel.GetElements("item");
                    foreach (var item in items)
                    {
                        var title = item.GetElementValue("title");
                        var link  = (string.IsNullOrEmpty(item.GetElementValue("link"))
                            ? item.GetElementValue("guid")
                            : item.GetElementValue("link"))
                                    .Trim();

                        var pubDate = GetPublishDate(item);
                        if (pubDate == default(DateTimeOffset))
                        {
                            continue;
                        }

                        var approvedCategories = new List <string> {
                            "umbraco", "codegarden", "articulate", "examine"
                        };
                        var categories = item.GetElements("category");
                        if (categories.Any())
                        {
                            var includeItem = title.ToLowerInvariant().ContainsAny(approvedCategories);
                            foreach (var category in categories)
                            {
                                // no need to check more if the item is already approved
                                if (includeItem)
                                {
                                    continue;
                                }

                                foreach (var approvedCategory in approvedCategories)
                                {
                                    if (category.Value.ToLowerInvariant().Contains(approvedCategory.ToLowerInvariant()))
                                    {
                                        includeItem = true;
                                    }
                                }
                            }

                            if (includeItem == false)
                            {
                                var allCategories = string.Join(",", categories.Select(i => i.Value));
                                context.SetTextColor(ConsoleTextColor.DarkYellow);
                                context.WriteLine($"Not including post titled {title} because it was not in an approved category. The categories it was found in: {allCategories}. [{link}]");
                                context.ResetTextColor();
                                continue;
                            }
                        }

                        // Blog has no category info and posts things unrelated to Umbraco, check there's related keywords in the title
                        if (blog.CheckTitles)
                        {
                            var includeItem = false;
                            foreach (var approvedCategory in approvedCategories)
                            {
                                if (title.ToLowerInvariant().Contains(approvedCategory.ToLowerInvariant()))
                                {
                                    includeItem = true;
                                }
                            }

                            // Blog post seems unrelated to Umbraco, skip it
                            if (includeItem == false)
                            {
                                continue;
                            }
                        }

                        var blogPost = new BlogRssItem
                        {
                            Channel = rssChannel,
                            Title   = title,
                            // some sites store the link in the <guid/> element
                            Link          = link,
                            PublishedDate = pubDate
                        };

                        posts.Add(blogPost);
                    }

                    // Get the avatar locally so that we can use ImageProcessor and serve it over https
                    using (var wc = new WebClient())
                    {
                        wc.Headers.Add(HttpRequestHeader.UserAgent, userAgent);
                        var baseLogoPath = HostingEnvironment.MapPath("~/media/blogs/");
                        if (Directory.Exists(baseLogoPath) == false)
                        {
                            Directory.CreateDirectory(baseLogoPath);
                        }

                        var logoExtension = GetFileExtension(blog.LogoUrl);
                        var logoPath      = baseLogoPath + blog.Id + logoExtension;

                        wc.DownloadFile(blog.LogoUrl, logoPath);
                    }
                }
                catch (Exception ex)
                {
                    context.SetTextColor(ConsoleTextColor.Red);
                    context.WriteLine("Unable to get blog posts for: " + blog.RssUrl, ex);
                    context.ResetTextColor();
                }
            }

            return(posts.OrderByDescending(x => x.PublishedDate).ToArray());
        }
Exemplo n.º 15
0
        public async Task Process(ThumbnailsTaskRunRequest generateRequest, ThumbnailProcessNotification notifyEvent, IJobCancellationToken cancellationToken, PerformContext context)
        {
            try
            {
                Action <ThumbnailTaskProgress> progressCallback = x =>
                {
                    notifyEvent.Description    = x.Message;
                    notifyEvent.Errors         = x.Errors;
                    notifyEvent.ErrorCount     = notifyEvent.Errors.Count;
                    notifyEvent.TotalCount     = x.TotalCount ?? 0;
                    notifyEvent.ProcessedCount = x.ProcessedCount ?? 0;
                    notifyEvent.JobId          = context.BackgroundJob.Id;

                    _pushNotifier.Send(notifyEvent);
                };

                //wrap token
                var tasks = await _taskService.GetByIdsAsync(generateRequest.TaskIds);

                var cancellationTokenWrapper = new JobCancellationTokenWrapper(cancellationToken);
                await _thumbnailProcessor.ProcessTasksAsync(tasks, generateRequest.Regenerate, progressCallback, cancellationTokenWrapper);

                //update tasks in case of successful generation
                foreach (var task in tasks)
                {
                    task.LastRun = DateTime.UtcNow;
                }

                await _taskService.SaveChangesAsync(tasks);
            }
            catch (JobAbortedException)
            {
                //do nothing
            }
            catch (Exception ex)
            {
                notifyEvent.Description = "Error";
                notifyEvent.ErrorCount++;
                notifyEvent.Errors.Add(ex.ToString());
            }
            finally
            {
                notifyEvent.Finished    = DateTime.UtcNow;
                notifyEvent.Description = "Process finished" + (notifyEvent.Errors.Any() ? " with errors" : " successfully");
                _pushNotifier.Send(notifyEvent);
            }
        }
Exemplo n.º 16
0
 public virtual JobActivatorScope BeginScope(PerformContext context)
 {
     return(this.BeginScope(new JobActivatorContext(context.Connection, context.BackgroundJob, context.CancellationToken)));
 }
        /// <summary>
        /// Hangfire job to send the daily export to OneStop
        /// </summary>
        public async Task SendLdbExport(PerformContext hangfireContext)
        {
            hangfireContext.WriteLine("Starting OneStop SendLdbExport Job.");

            // Get data

            List <MicrosoftDynamicsCRMadoxioLicences> result = null;
            string filter = $"adoxio_businessprogramaccountreferencenumber eq null";
            var    expand = new List <string> {
                "adoxio_Licencee", "adoxio_establishment"
            };

            try
            {
                result = _dynamics.Licenceses.Get(filter: filter, expand: expand).Value.ToList();
            }
            catch (OdataerrorException odee)
            {
                hangfireContext.WriteLine("Error getting Licence data rows");
                hangfireContext.WriteLine("Request:");
                hangfireContext.WriteLine(odee.Request.Content);
                hangfireContext.WriteLine("Response:");
                hangfireContext.WriteLine(odee.Response.Content);
                // fail if we can't get results.
                throw (odee);
            }

            if (result == null || result.Count == 0)
            {
                bool sent = SendNoResultsEmail();
                if (sent)
                {
                    hangfireContext.WriteLine("Sent No Results Email.");
                }
                else
                {
                    hangfireContext.WriteLine("Unable to send No Results Email.");
                }
            }
            else
            {
                // Create the CSV for LDB
                var csvList          = new List <List <string> >();
                var headers          = new List <string>();
                var headerDefinition = GetExportHeaders();
                headerDefinition.ForEach(h =>
                {
                    headers.Add($"\"{h.Value}\"");
                });

                csvList.Add(headers);



                if (result != null && result.Count > 0)
                {
                    foreach (var row in result)
                    {
                        var item = new List <string>();

                        foreach (var h in headerDefinition)
                        {
                            try
                            {
                                object value = row[h.Key];
                                if (value != null)
                                {
                                    item.Add($"\"{value.ToString()}\"");
                                }
                                else
                                {
                                    item.Add("\"\"");
                                }
                            }
                            catch (Exception)
                            {
                                item.Add("\"\"");;
                            }
                        }
                        csvList.Add(item);
                    }
                }

                var csv = new StringBuilder();
                csvList.ForEach(row =>
                {
                    var line = String.Join(",", row);
                    csv.AppendLine(line);
                });

                var datePart = DateTime.Now.ToString("yyyyMMdd_HHmmss");

                var attachmentName = $@"LdbExport_{datePart}.csv";

                // Send as email
                bool emailSuccess = SendCsvEmail(csv.ToString(), attachmentName);
                // Upload to SharePoint
                bool uploadSuccess = true;

                if (emailSuccess || uploadSuccess)
                {
                    hangfireContext.WriteLine("Sent CSV export");
                }
            }

            hangfireContext.WriteLine("End ofOneStop SendLdbExport  Job.");
        }
Exemplo n.º 18
0
        /// <summary>
        /// Run HttpRequest
        /// </summary>
        /// <param name="item"></param>
        /// <param name="context"></param>
        /// <param name="logList"></param>
        /// <param name="parentJob"></param>
        /// <exception cref="HttpStatusCodeException"></exception>
        private static bool Run(HttpJobItem item, PerformContext context, List <string> logList, HttpJobItem parentJob = null)
        {
            CancellationTokenSource cancelToken = null;

            try
            {
                if (parentJob != null)
                {
                    RunWithTry(() => context.SetTextColor(ConsoleTextColor.Green));
                    if (item.Timeout < 1)
                    {
                        item.Timeout = parentJob.Timeout;
                    }
                    if (item.Data.Contains("@parent@"))
                    {
                        item.Data = item.Data.Replace("@parent@", parentJob.Cron);
                    }
                    if (string.IsNullOrEmpty(item.BasicUserName))
                    {
                        item.BasicUserName = parentJob.BasicUserName;
                    }
                    if (string.IsNullOrEmpty(item.BasicPassword))
                    {
                        item.BasicPassword = parentJob.BasicPassword;
                    }
                    if (item.Headers == null || !item.Headers.Any())
                    {
                        item.Headers = parentJob.Headers;
                    }
                    if (string.IsNullOrEmpty(item.QueueName))
                    {
                        item.QueueName = parentJob.QueueName;
                    }
                    RunWithTry(() => context.WriteLine($"【{Strings.CallbackStart}】[{item.CallbackRoot}]"));
                    item.JobName = item.CallbackRoot;
                }
                else
                {
                    if (string.IsNullOrEmpty(item.CallbackRoot))
                    {
                        item.CallbackRoot = item.JobName;
                    }
                    if (item.Timeout < 1)
                    {
                        item.Timeout = 5000;
                    }
                    RunWithTry(() => context.SetTextColor(ConsoleTextColor.Yellow));
                }


                RunWithTry(() => context.WriteLine($"{Strings.JobStart}:{DateTime.Now:yyyy-MM-dd HH:mm:ss}"));
                logList.Add($"{Strings.JobStart}:{DateTime.Now:yyyy-MM-dd HH:mm:ss}");
                RunWithTry(() => context.WriteLine($"{Strings.JobName}:{item.JobName ?? string.Empty}|{Strings.QueuenName}:{(string.IsNullOrEmpty(item.QueueName) ? "DEFAULT" : item.QueueName)}"));
                logList.Add(
                    $"{Strings.JobName}:{item.JobName ?? string.Empty}|{Strings.QueuenName}:{(string.IsNullOrEmpty(item.QueueName) ? "DEFAULT" : item.QueueName)}");
                RunWithTry(() => context.WriteLine($"{Strings.JobParam}:【{JsonConvert.SerializeObject(item)}】"));
                logList.Add($"{Strings.JobParam}:【{JsonConvert.SerializeObject(item, Formatting.Indented)}】");
                HttpClient client;

                //当前job指定如果开启了proxy 并且 有配置代理 那么就走代理
                if (CodingUtil.TryGetGlobalProxy(out var globalProxy) && item.Headers != null && item.Headers.TryGetValue("proxy", out var enableCurrentJobProxy) && !string.IsNullOrEmpty(enableCurrentJobProxy) && enableCurrentJobProxy.ToLower().Equals("true"))
                {
                    // per proxy per HttpClient
                    client = HangfireHttpClientFactory.Instance.GetProxiedHttpClient(globalProxy);
                    RunWithTry(() => context.WriteLine($"Use Proxy:{globalProxy}"));
                    logList.Add($"Proxy:{globalProxy}");
                }
                else
                {
                    //per host per HttpClient
                    client = HangfireHttpClientFactory.Instance.GetHttpClient(item.Url);
                }

                var httpMesage = PrepareHttpRequestMessage(item, context, parentJob);
                cancelToken = new CancellationTokenSource(TimeSpan.FromMilliseconds(item.Timeout));
                var         httpResponse = client.SendAsync(httpMesage, cancelToken.Token).ConfigureAwait(false).GetAwaiter().GetResult();
                HttpContent content      = httpResponse.Content;
                string      result       = content.ReadAsStringAsync().GetAwaiter().GetResult();
                RunWithTry(() => context.WriteLine($"{Strings.ResponseCode}:{httpResponse.StatusCode}"));
                logList.Add($"{Strings.ResponseCode}:{httpResponse.StatusCode}");
                RunWithTry(() => context.WriteLine($"{Strings.JobResult}:{result}"));
                logList.Add($"{Strings.JobResult}:{result}");
                RunWithTry(() => context.WriteLine($"{Strings.JobEnd}:{DateTime.Now:yyyy-MM-dd HH:mm:ss}"));
                logList.Add($"{Strings.JobEnd}:{DateTime.Now:yyyy-MM-dd HH:mm:ss}");
                //如果agent那边调度报错
                if (CodingUtil.HangfireHttpJobOptions.EnableJobAgentErrorThrow && !string.IsNullOrEmpty(item.AgentClass) && httpResponse.StatusCode == HttpStatusCode.InternalServerError)
                {
                    throw new AgentJobException(item.AgentClass, result);
                }
                //检查HttpResponse StatusCode
                else if (CodingUtil.HangfireHttpJobOptions.CheckHttpResponseStatusCode(httpResponse.StatusCode, result))
                {
                    RunWithTry(() => context.WriteLine($"{Strings.ResponseCode}:{httpResponse.StatusCode} ===> CheckResult: Ok "));
                    logList.Add($"{Strings.ResponseCode}:{httpResponse.StatusCode} ===> CheckResult: Ok ");
                }
                else
                {
                    //错误的log都会在exception里面出
                    throw new HttpStatusCodeException(httpResponse.StatusCode, result);
                }

                //检查是否有设置EL表达式 可以自定义检查StatusCode 和 解析返回的参数值
                if (!string.IsNullOrEmpty(item.CallbackEL))
                {
                    var elResult = InvokeSpringElCondition(item.CallbackEL, result, context,
                                                           new Dictionary <string, object> {
                        { "resultBody", result }, { "StatusCode", (int)httpResponse.StatusCode }
                    });
                    if (!elResult)
                    {
                        //错误的log都会在exception里面出
                        throw new HttpStatusCodeException(item.CallbackEL, result);
                    }

                    RunWithTry(() => context.WriteLine($"【{Strings.CallbackELExcuteResult}:Ok 】" + item.CallbackEL));
                }


                if (parentJob != null)
                {
                    RunWithTry(() => context.WriteLine($"【{Strings.CallbackSuccess}】[{item.CallbackRoot}]"));
                }

                //到这里查看是否有 子Job
                if (item.Success != null)
                {
                    item.Cron = result; //父job的执行结果
                    item.Success.CallbackRoot = item.CallbackRoot + ".Success";
                    return(Run(item.Success, context, logList, item));
                }

                return(true);
            }
Exemplo n.º 19
0
 internal PerformingContext(
     PerformContext context)
     : base(context)
 {
 }
Exemplo n.º 20
0
 /// <summary>
 /// Begins a logical operation scope for the given <see cref="PerformContext"/> within the scope of a job.
 /// </summary>
 /// <param name="logger">The <see cref="ILogger"/> instance.</param>
 /// <param name="performContext">The <see cref="PerformContext"/> instance for the job.</param>
 public static IDisposable BeginJobScope(this ILogger logger, PerformContext performContext) =>
 performContext != null?logger.BeginScope(new PerformContextWrapper(performContext)) : NoopDisposable.Instance;
Exemplo n.º 21
0
        public async Task NotifyService(SonarrWebhookPayload importPayload, bool isTest, PerformContext performContext)
        {
            var path = isTest ? "test.mkv" : importPayload.Series.Path + "/" + importPayload.EpisodeFile.RelativePath;

            this.logger.LogInformation($"Informing Sonarr of conversion result path: {path}");
            performContext.WriteLine($"Informing Sonarr of conversion result path: {path}");

            var response = await this.sonarrProxy.ExecuteCommand(this.settingsService.Settings.SonarrApiKey, new SonarrCommand()
            {
                Name     = "RescanSeries",
                SeriesId = isTest ? 10 : importPayload.Series.Id
            });

            performContext.WriteLine($"Sonarr response: {response.State}");
            this.logger.LogInformation($"Sonarr response: {response.State}");
        }
Exemplo n.º 22
0
        private static object[] SubstituteArguments(PerformContext context)
        {
            var parameters = context.BackgroundJob.Job.Method.GetParameters();
            var result = new List<object>(context.BackgroundJob.Job.Args.Count);

            for (var i = 0; i < parameters.Length; i++)
            {
                var parameter = parameters[i];
                var argument = context.BackgroundJob.Job.Args[i];

                var value = Substitutions.ContainsKey(parameter.ParameterType) 
                    ? Substitutions[parameter.ParameterType](context) 
                    : argument;

                result.Add(value);
            }

            return result.ToArray();
        }
 public void ManageProduct(Guid productId, PerformContext context)
 {
     ManageProductAsync(productId, null).Wait();
 }
Exemplo n.º 24
0
        private void PerformJob(IStorageConnection connection, JobPayload payload)
        {
            if (payload == null)
            {
                return;
            }

            var stateMachine = new StateMachine(connection);
            var processingState = new ProcessingState(_context.ServerName);

            if (!stateMachine.TryToChangeState(
                payload.Id, 
                processingState, 
                new [] { EnqueuedState.StateName, ProcessingState.StateName }))
            {
                return;
            }

            // Checkpoint #3. Job is in the Processing state. However, there are
            // no guarantees that it was performed. We need to re-queue it even
            // it was performed to guarantee that it was performed AT LEAST once.
            // It will be re-queued after the JobTimeout was expired.

            State state;

            try
            {
                IJobPerformStrategy performStrategy;

                var methodData = MethodData.Deserialize(payload.InvocationData);
                if (methodData.OldFormat)
                {
                    // For compatibility with the Old Client API.
                    // TODO: remove it in version 1.0
                    var arguments = JobHelper.FromJson<Dictionary<string, string>>(
                        payload.Args);

                    performStrategy = new JobAsClassPerformStrategy(
                        methodData, arguments);
                }
                else
                {
                    var arguments = JobHelper.FromJson<string[]>(payload.Arguments);

                    performStrategy = new JobAsMethodPerformStrategy(
                        methodData, arguments);
                }
                
                var performContext = new PerformContext(_context, connection, payload.Id, methodData);
                _context.PerformancePipeline.Run(performContext, performStrategy);

                state = new SucceededState();
            }
            catch (JobPerformanceException ex)
            {
                state = new FailedState(ex.InnerException)
                {
                    Reason = ex.Message
                };
            }
            catch (Exception ex)
            {
                state = new FailedState(ex)
                {
                    Reason = "Internal HangFire Server exception occurred. Please, report it to HangFire developers."
                };
            }

            // TODO: check return value
            stateMachine.TryToChangeState(payload.Id, state, new [] { ProcessingState.StateName });
        }
        private async Task <ImportResult> ValidateAndImportNotificationGroupAsync(PerformContext context, string requestId, List <Notification> notifications)
        {
            var patientName  = notifications.First().PatientDetails.FullName;
            var importResult = new ImportResult(patientName);

            _logger.LogInformation(context, requestId, $"{notifications.Count} notifications found to import for {patientName}");

            // Verify that no repeated NotificationIds have returned
            var ids = notifications.Select(n => n.LegacyId).ToList();

            if (ids.Distinct().Count() != ids.Count)
            {
                var errorMessage = $"Duplicate records found ({String.Join(',', ids)}) - aborting import for {patientName}";
                importResult.AddGroupError(errorMessage);
                _logger.LogImportFailure(context, requestId, errorMessage);
                return(importResult);
            }

            bool isAnyNotificationInvalid = false;

            foreach (var notification in notifications)
            {
                var linkedNotificationId = notification.LegacyId;
                _logger.LogInformation(context, requestId, $"Validating notification with Id={linkedNotificationId}");

                var validationErrors = await _importValidator.CleanAndValidateNotification(context,
                                                                                           requestId,
                                                                                           notification);

                if (!validationErrors.Any())
                {
                    _logger.LogInformation(context, requestId, "No validation errors found");
                    importResult.AddValidNotification(linkedNotificationId);
                }
                else
                {
                    isAnyNotificationInvalid = true;
                    importResult.AddValidationErrorsMessages(linkedNotificationId, validationErrors);
                    _logger.LogWarning(context, requestId, $"{validationErrors.Count} validation errors found for notification with Id={linkedNotificationId}:");
                    foreach (var validationError in validationErrors)
                    {
                        _logger.LogWarning(context, requestId, validationError.ErrorMessage);
                    }
                }
            }

            if (isAnyNotificationInvalid)
            {
                _logger.LogImportFailure(context, requestId, $"Terminating importing notifications for {patientName} due to validation errors");
                return(importResult);
            }

            _logger.LogSuccess(context, requestId, $"Importing {notifications.Count} valid notifications");
            try
            {
                var savedNotifications = await _notificationImportRepository.AddLinkedNotificationsAsync(notifications);

                await _migratedNotificationsMarker.MarkNotificationsAsImportedAsync(savedNotifications);

                importResult.NtbsIds = savedNotifications.ToDictionary(x => x.LegacyId, x => x.NotificationId);
                await ImportReferenceLabResultsAsync(context, requestId, savedNotifications, importResult);

                var newIdsString = string.Join(" ,", savedNotifications.Select(x => x.NotificationId));
                _logger.LogSuccess(context, requestId, $"Imported notifications have following Ids: {newIdsString}");

                _logger.LogInformation(context, requestId, $"Finished importing notification for {patientName}");
            }
            catch (MarkingNotificationsAsImportedFailedException e)
            {
                Log.Error(e, e.Message);
                _logger.LogWarning(context, requestId, message: e.Message);
                importResult.AddGroupError($"{e.Message}: {e.StackTrace}");
            }
            catch (Exception e)
            {
                Log.Error(e, e.Message);
                _logger.LogImportFailure(context, requestId, message: $"Failed to save notification for {patientName} or mark it as imported ", e);
                importResult.AddGroupError($"{e.Message}: {e.StackTrace}");
            }
            return(importResult);
        }
 public void RunDemoTask(PerformContext context)
 {
     Console.WriteLine("This is a task that ran from the demo service.");
     BackgroundJob.ContinueJobWith(context.BackgroundJob.Id, () => NextJob());
 }
        protected bool IsLastAttempt(PerformContext context, IPerformContextAdapter adapter)
        {
            var currentAttempt = CurrentAttempt(context, adapter);

            return(currentAttempt >= JobConfiguration.Attempts(Env));
        }
Exemplo n.º 28
0
        public static void Excute(HttpJobItem item, string jobName = null, string queuename = null, bool isretry = false, PerformContext context = null)
        {
            var logList = new List <string>();
            var result  = false;

            try
            {
                object runTimeDataItem = null;
                context?.Items.TryGetValue("Data", out runTimeDataItem);
                if (runTimeDataItem != null)
                {
                    var runTimeData = runTimeDataItem as string;
                    if (!string.IsNullOrEmpty(runTimeData))
                    {
                        item.Data = runTimeData;
                    }
                }

                if (Run(item, context, logList))
                {
                    SendSuccess(context.BackgroundJob.Id, item, string.Join("<br/>", logList));
                    result = true;
                }
                else
                {
                    SendFail(context.BackgroundJob.Id, item, string.Join("<br/>", logList), null);
                }
            }
            catch (Exception ex)
            {
                var statusCodeEx = ex as HttpStatusCodeException;
                RunWithTry(() => context.SetTextColor(ConsoleTextColor.Red));
                Logger.ErrorException("HttpJob.Excute=>" + item, ex);
                if (statusCodeEx != null && statusCodeEx.IsEl)
                {
                    RunWithTry(() => context.WriteLine($"【{Strings.CallbackELExcuteResult}:Fail 】" + statusCodeEx.El));
                }
                else
                {
                    RunWithTry(() => context.WriteLine(ex.ToString()));
                }

                if (!item.EnableRetry)
                {
                    if (item.Fail != null)
                    {
                        item.Fail.CallbackRoot = item.JobName + ".Fail";
                        item.Cron = statusCodeEx == null || string.IsNullOrEmpty(statusCodeEx.Msg) ? ex.Message : statusCodeEx.Msg;
                        if (Run(item.Fail, context, logList, item))
                        {
                            SendSuccess(context.BackgroundJob.Id, item, string.Join("<br/>", logList));
                            return;
                        }
                    }
                    SendFail(context.BackgroundJob.Id, item, string.Join("<br/>", logList), ex);
                    AddErrToJob(context, ex);
                    throw;
                }

                //获取重试次数
                var count = RunWithTry <string>(() => context.GetJobParameter <string>("RetryCount")) ?? string.Empty;
                if (count == "3") //重试达到三次的时候发邮件通知
                {
                    if (item.Fail != null)
                    {
                        item.Fail.CallbackRoot = item.JobName + ".Fail";
                        item.Cron = statusCodeEx == null || string.IsNullOrEmpty(statusCodeEx.Msg) ? ex.Message : statusCodeEx.Msg;
                        if (Run(item.Fail, context, logList, item))
                        {
                            SendSuccess(context.BackgroundJob.Id, item, string.Join("<br/>", logList));
                            return;
                        }
                    }
                    RunWithTry(() => context.WriteLine(Strings.LimitReached));
                    logList.Add(Strings.LimitReached);
                    SendFail(context.BackgroundJob.Id, item, string.Join("<br/>", logList), ex);
                    AddErrToJob(context, ex);
                    return;
                }

                context?.Items.Add("RetryCount", count);
                throw;
            }

            if (!result)
            {
                throw new CallbackJobException("Callback job Fail");
            }
        }
 protected int CurrentAttempt(PerformContext context, IPerformContextAdapter adapter)
 {
     return(adapter.GetRetryCount(context) + 1);
 }
Exemplo n.º 30
0
 public object Perform(PerformContext context)
 {
     Console.WriteLine($"Perform {context.BackgroundJob.Id} ({context.BackgroundJob.Job.Type.FullName}.{context.BackgroundJob.Job.Method.Name})");
     return(_inner.Perform(context));
 }
 protected string AttemptInfo(PerformContext context, IPerformContextAdapter adapter)
 {
     return($"{CurrentAttempt(context, adapter)}/{JobConfiguration.Attempts(Env)}");
 }
 public async Task RefreshIndexAsync(PerformContext context, string projectId, string branchName)
 {
     await _queuesService.AddToQueueAsync(projectId, branchName);
 }
        public static void BuildCache(PerformContext context)
        {
            int batchSize = 10;

            try
            {
                //get bc height from RPC
                var currentHeight = 0;
                try
                {
                    currentHeight = RpcHelper.Request <GetHeightResp>("getheight").Height;
                }
                catch
                {
                    currentHeight = 0;
                }
                var startHeight = 1;
                var endHeight   = Convert.ToInt32(Math.Ceiling((double)(currentHeight / 10000) * 10000)) + 10000;
                logger.Log(LogLevel.Information, $"Processing transactions from blocks {startHeight} to {endHeight}");
                var clearCache = false;
                var firstPass  = true;
                //now, splt the current height into blocks of 10000
                for (int i = startHeight; i <= endHeight; i += 10000)
                {
                    var start = i;
                    var end   = i + 10000 - 1;
                    if (clearCache)
                    {
                        if (firstPass) //delete the previous file if we've cought an error
                        {
                            //this file should always exist as it's the one we cought the re-organsisation in
                            System.IO.File.Delete(string.Concat(AppContext.BaseDirectory, @"App_Data/", "transactions_", (start - 10000), "-", (end - 10000), ".db"));
                            firstPass = false;
                        }
                        if (System.IO.File.Exists(string.Concat(AppContext.BaseDirectory, @"App_Data/", "transactions_", start, "-", end, ".db")))
                        {
                            System.IO.File.Delete(string.Concat(AppContext.BaseDirectory, @"App_Data/", "transactions_", start, "-", end, ".db"));
                        }
                        else
                        {
                            //we haven't created this file yet, so we can start to re-cache now...
                        }
                    }
                    else
                    {
                        //retreive, transform and cache the blockchain and store in LiteDB
                        using (var db = new LiteDatabase(string.Concat(AppContext.BaseDirectory, @"App_Data/", "transactions_", start, "-", end, ".db")))
                        {
                            var transactions = db.GetCollection <CachedTx>("cached_txs");
                            var date         = DateTime.Now;
                            // Index document using height's, hash and Id
                            transactions.EnsureIndex(x => x.height);
                            transactions.EnsureIndex(x => x.Id);
                            transactions.EnsureIndex(x => x.hash);

                            try
                            {
                                //get the maxTxId
                                var lastTxId = transactions.Max(x => x.Id).AsInt32;
                                //get the last Tx we cached
                                var lastTx = transactions.FindOne(x => x.Id == lastTxId);
                                if (lastTx != null)
                                {
                                    start = lastTx.height;
                                    var lastHash = lastTx.hash;
                                    if (start == end - 1)
                                    {
                                        logger.Log(LogLevel.Information, $"Already cached transactions from blocks {startHeight} to {endHeight}");
                                        logger.Log(LogLevel.Information, $"Checking for changes to hash '{lastHash}' at height {start}");

                                        //query the node to make sure thew hash at this height still matches the one in the cache...
                                        List <int> blockHeights = new List <int>();
                                        blockHeights.Add(start);
                                        var args = new Dictionary <string, object>();
                                        args.Add("blockHeights", blockHeights);
                                        var block     = RpcHelper.Request <BlockResp>("get_blocks_details_by_heights", args).blocks.FirstOrDefault();
                                        var foundHash = false;
                                        if (block != null)
                                        {
                                            foreach (var transaction in block.transactions)
                                            {
                                                if (transaction.hash == lastTx.hash)
                                                {
                                                    foundHash = true;
                                                }
                                            }
                                        }

                                        if (!foundHash)
                                        {
                                            //we have not found the hash in the block, so something has changed...
                                            //set the clearCache var so it deletes previous cache files on the next pass and then re-caches...
                                            clearCache = true;
                                            logger.Log(LogLevel.Information, $"hash '{lastHash}' not found at height {start}. Recaching...");
                                        }
                                        continue; //continue with the loop to clear the subsequent files...
                                    }
                                }
                                else
                                {
                                    start = i;
                                }
                            }
                            catch (Exception ex)
                            {
                                LogException(ex);
                            }
                            //TODO: This is Currently re-importing the last 1000 blocks in every batch... need to fix that and add in a checking mechanism to
                            //get it re-checking cached files...
                            if (currentHeight > start)
                            {
                                var counter = start;
                                if (end > currentHeight)
                                {
                                    end = currentHeight;
                                }
                                try
                                {
                                    var startBlock = (start / batchSize) * batchSize; //get the first "batch of 1000 to start with
                                    for (var y = startBlock; y <= end; y += batchSize)
                                    {
                                        var        endBlock     = end < y + batchSize ? end : y + batchSize;
                                        List <int> blockHeights = new List <int>();
                                        for (var x = y; x < endBlock; x++)
                                        {
                                            blockHeights.Add(x);
                                        }
                                        if (blockHeights.Any())
                                        {
                                            //fetch the transactions
                                            var args = new Dictionary <string, object>();
                                            args.Add("blockHeights", blockHeights);
                                            var blocksResponse = RpcHelper.Request <BlockResp>("get_blocks_details_by_heights", args);
                                            if (blocksResponse.blocks != null)
                                            {
                                                List <CachedTx> transactionsToInsert = new List <CachedTx>();
                                                foreach (var block in blocksResponse.blocks)
                                                {
                                                    foreach (var transaction in block.transactions)
                                                    {
                                                        var cachedTx = TransactionHelpers.MapTx(transaction);
                                                        //persist tx's to cache
                                                        if (cachedTx != null && !transactions.Find(x => x.hash == cachedTx.hash).Any())
                                                        {
                                                            transactionsToInsert.Add(cachedTx);
                                                        }
                                                    }
                                                }
                                                if (transactionsToInsert.Any())
                                                {
                                                    transactions.InsertBulk(transactionsToInsert);
                                                }
                                            }
                                            else
                                            {
                                                //try again with a smaller batch size, maybe do these in 10 block batches ?
                                            }
                                        }
                                    }
                                }
                                catch (Exception ex)
                                {
                                    LogException(ex);
                                }
                            }
                            //else there's nothing to do
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                LogException(ex);
            }
            finally
            {
                logger.Log(LogLevel.Information, $"Job Completed, rescheduling...");
                //finally, schedule the next check in 30 seconds time
                BackgroundJob.Schedule(() => BlockchainCache.BuildCache(null), TimeSpan.FromSeconds(30));
            }
        }
Exemplo n.º 34
0
        public async Task ExportBackgroundAsync(ExportDataRequest request, ExportPushNotification notification, IJobCancellationToken cancellationToken, PerformContext context)
        {
            void progressCallback(ExportProgressInfo x)
            {
                notification.Patch(x);
                notification.JobId = context.BackgroundJob.Id;
                _pushNotificationManager.Send(notification);
            }

            try
            {
                if (string.IsNullOrEmpty(_platformOptions.DefaultExportFolder))
                {
                    throw new PlatformException($"{nameof(_platformOptions.DefaultExportFolder)} should be set.");
                }

                var fileName = string.Format(FileNameTemplate, DateTime.UtcNow);

                // Do not like provider creation here to get file extension, maybe need to pass created provider to Exporter.
                // Create stream inside Exporter is not good as it is not Exporter resposibility to decide where to write.
                var provider = _exportProviderFactory.CreateProvider(request);

                if (!string.IsNullOrEmpty(provider.ExportedFileExtension))
                {
                    fileName = Path.ChangeExtension(fileName, provider.ExportedFileExtension);
                }

                var url = UrlHelperExtensions.Combine(_platformOptions.DefaultExportFolder, fileName);
                using (var blobStream = _blobStorageProvider.OpenWrite(url))
                {
                    _dataExporter.Export(blobStream, request, progressCallback, new JobCancellationTokenWrapper(cancellationToken));
                }

                notification.DownloadUrl = _blobUrlResolver.GetAbsoluteUrl(url);
            }
            catch (JobAbortedException)
            {
                //do nothing
            }
            catch (Exception ex)
            {
                notification.Errors.Add(ex.ExpandExceptionMessage());
            }
            finally
            {
                notification.Description = "Export finished";
                notification.Finished    = DateTime.UtcNow;
                await _pushNotificationManager.SendAsync(notification);
            }
        }
Exemplo n.º 35
0
        private static HttpRequestMessage PrepareHttpRequestMessage(HttpJobItem item, PerformContext context)
        {
            var request = new HttpRequestMessage(new HttpMethod(item.Method), item.Url);

            request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue(item.ContentType));
            if (!item.Method.ToLower().Equals("get"))
            {
                if (!string.IsNullOrEmpty(item.Data))
                {
                    //var bytes = Encoding.UTF8.GetBytes(item.Data);
                    request.Content = new StringContent(item.Data, Encoding.UTF8, item.ContentType);
                    //request.Content = new ByteArrayContent(bytes, 0, bytes.Length);
                }
            }

            var headerKeys = string.Empty;

            if (item.Headers != null && item.Headers.Count > 0)
            {
                foreach (var header in item.Headers)
                {
                    if (string.IsNullOrEmpty(header.Key))
                    {
                        continue;
                    }
                    request.Headers.Add(header.Key, header.Value);
                }

                headerKeys = string.Join(";", item.Headers.Keys);
            }

            if (!string.IsNullOrEmpty(item.AgentClass))
            {
                request.Headers.Add("x-job-agent-class", item.AgentClass);
                if (!string.IsNullOrEmpty(headerKeys))
                {
                    request.Headers.Add("x-job-agent-header", headerKeys);
                }
                var consoleInfo = GetConsoleInfo(context);
                if (consoleInfo != null)
                {
                    request.Headers.Add("x-job-agent-console", JsonConvert.SerializeObject(consoleInfo));
                }
            }

            if (context != null)
            {
                context.Items.TryGetValue("Action", out var actionItem);
                var action = actionItem as string;
                if (!string.IsNullOrEmpty(action))
                {
                    request.Headers.Add("x-job-agent-action", action);
                }
                else if (!string.IsNullOrEmpty(item.AgentClass))
                {
                    request.Headers.Add("x-job-agent-action", "run");
                }
            }

            if (!string.IsNullOrEmpty(item.BasicUserName) && !string.IsNullOrEmpty(item.BasicPassword))
            {
                var byteArray = Encoding.ASCII.GetBytes(item.BasicUserName + ":" + item.BasicPassword);
                request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", Convert.ToBase64String(byteArray));
            }

            return(request);
        }
 private ConsoleContext CreateConsoleContext(PerformContext context)
 {
     return(new ConsoleContext(
                new ConsoleId(context.BackgroundJob.Id, DateTime.UtcNow),
                new ConsoleStorage(context.Connection)));
 }
Exemplo n.º 37
0
 public AsyncLocalScope(PerformContext context) => PerformContext.Value = context;
Exemplo n.º 38
0
 public void InstanceTestJob(PerformContext context)
 {
     context.WriteLine($"{DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss")} InstanceTestJob Running ...");
 }
Exemplo n.º 39
0
        public void Execute(TestJobArg arg, PerformContext context)
        {
            Console.WriteLine(arg.ToString());

            context.WriteLine($" context - {arg} , helper - {_constHelper.Test()}");
        }
Exemplo n.º 40
0
 public static void StaticTestJob(PerformContext context)
 {
     Console.WriteLine($"{DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss")} StaticTestJob Running ...");
 }
Exemplo n.º 41
0
        private IState PerformJob(string jobId, IStorageConnection connection, IJobCancellationToken token)
        {
            try
            {
                var jobData = connection.GetJobData(jobId);
                if (jobData == null)
                {
                    // Job expired just after moving to a processing state. This is an
                    // unreal scenario, but shit happens. Returning null instead of throwing
                    // an exception and rescuing from en-queueing a poisoned jobId back
                    // to a queue.
                    return null;
                }

                jobData.EnsureLoaded();

                var performContext = new PerformContext(
                    _context, connection, jobId, jobData.Job, jobData.CreatedAt, token);

                var latency = (DateTime.UtcNow - jobData.CreatedAt).TotalMilliseconds;
                var duration = Stopwatch.StartNew();

                var result = _process.Run(performContext, jobData.Job);
                duration.Stop();

                return new SucceededState(result, (long) latency, duration.ElapsedMilliseconds);
            }
            catch (OperationCanceledException)
            {
                throw;
            }
            catch (JobPerformanceException ex)
            {
                return new FailedState(ex.InnerException)
                {
                    Reason = ex.Message
                };
            }
            catch (Exception ex)
            {
                return new FailedState(ex)
                {
                    Reason = "Internal Hangfire Server exception occurred. Please, report it to Hangfire developers."
                };
            }
        }
Exemplo n.º 42
0
 public static IDisposable InContext(PerformContext context) => new AsyncLocalScope(context);
Exemplo n.º 43
0
 private static object InvokeMethod(PerformContext context, object instance, object[] arguments)
 {
     try
     {
         return context.BackgroundJob.Job.Method.Invoke(instance, arguments);
     }
     catch (ArgumentException ex)
     {
         HandleJobPerformanceException(ex, context.CancellationToken.ShutdownToken);
         throw;
     }
     catch (TargetInvocationException ex)
     {
         HandleJobPerformanceException(ex.InnerException, context.CancellationToken.ShutdownToken);
         throw;
     }
 }
Exemplo n.º 44
0
 private static void AddErrToJob(PerformContext context, Exception ex)
 {
     context.SetJobParameter("jobErr", ex.Message);
 }
 public void Execute(PerformContext context)
 {
     // Execute business logic
     _csvFileHandlerManager.HandleCsvFiles();
 }
Exemplo n.º 46
0
        private IState PerformJob(BackgroundProcessContext context, IStorageConnection connection, string jobId)
        {
            try
            {
                var jobData = connection.GetJobData(jobId);
                if (jobData == null)
                {
                    // Job expired just after moving to a processing state. This is an
                    // unreal scenario, but shit happens. Returning null instead of throwing
                    // an exception and rescuing from en-queueing a poisoned jobId back
                    // to a queue.
                    return null;
                }

                jobData.EnsureLoaded();

                var backgroundJob = new BackgroundJob(jobId, jobData.Job, jobData.CreatedAt);

                var jobToken = new ServerJobCancellationToken(connection, jobId, context.ServerId, _workerId, context.CancellationToken);
                var performContext = new PerformContext(connection, backgroundJob, jobToken);

                var latency = (DateTime.UtcNow - jobData.CreatedAt).TotalMilliseconds;
                var duration = Stopwatch.StartNew();

                var result = _performer.Perform(performContext);
                duration.Stop();

                return new SucceededState(result, (long) latency, duration.ElapsedMilliseconds);
            }
            catch (OperationCanceledException)
            {
                throw;
            }
            catch (JobPerformanceException ex)
            {
                return new FailedState(ex.InnerException)
                {
                    Reason = ex.Message
                };
            }
            catch (Exception ex)
            {
                return new FailedState(ex)
                {
                    Reason = "An exception occurred during processing of a background job."
                };
            }
        }
Exemplo n.º 47
0
        public static void Excute(HttpJobItem item, string jobName = null, string queuename = null, bool isretry = false, PerformContext context = null)
        {
            var logList = new List <string>();

            try
            {
                if (context == null)
                {
                    return;
                }
                context.Items.TryGetValue("Data", out var runTimeDataItem);
                var runTimeData = runTimeDataItem as string;
                if (!string.IsNullOrEmpty(runTimeData))
                {
                    item.Data = runTimeData;
                }
                if (item.Timeout < 1)
                {
                    item.Timeout = 5000;
                }
                RunWithTry(() => context.SetTextColor(ConsoleTextColor.Yellow));
                RunWithTry(() => context.WriteLine($"{Strings.JobStart}:{DateTime.Now:yyyy-MM-dd HH:mm:ss}"));
                logList.Add($"{Strings.JobStart}:{DateTime.Now:yyyy-MM-dd HH:mm:ss}");
                RunWithTry(() => context.WriteLine($"{Strings.JobName}:{item.JobName ?? string.Empty}|{Strings.QueuenName}:{(string.IsNullOrEmpty(item.QueueName) ? "DEFAULT":item.QueueName)}"));
                logList.Add($"{Strings.JobName}:{item.JobName ?? string.Empty}|{Strings.QueuenName}:{(string.IsNullOrEmpty(item.QueueName) ? "DEFAULT" : item.QueueName)}");
                RunWithTry(() => context.WriteLine($"{Strings.JobParam}:【{JsonConvert.SerializeObject(item)}】"));
                logList.Add($"{Strings.JobParam}:【{JsonConvert.SerializeObject(item, Formatting.Indented)}】");
                HttpClient client;
                if (!string.IsNullOrEmpty(HangfireHttpJobOptions.Proxy))
                {
                    // per proxy per HttpClient
                    client = HangfireHttpClientFactory.Instance.GetProxiedHttpClient(HangfireHttpJobOptions.Proxy);
                    RunWithTry(() => context.WriteLine($"Proxy:{HangfireHttpJobOptions.Proxy}"));
                    logList.Add($"Proxy:{HangfireHttpJobOptions.Proxy}");
                }
                else
                {
                    //per host per HttpClient
                    client = HangfireHttpClientFactory.Instance.GetHttpClient(item.Url);
                }
                var         httpMesage   = PrepareHttpRequestMessage(item, context);
                var         cts          = new CancellationTokenSource(TimeSpan.FromMilliseconds(item.Timeout));
                var         httpResponse = client.SendAsync(httpMesage, cts.Token).ConfigureAwait(false).GetAwaiter().GetResult();
                HttpContent content      = httpResponse.Content;
                string      result       = content.ReadAsStringAsync().GetAwaiter().GetResult();
                RunWithTry(() => context.WriteLine($"{Strings.ResponseCode}:{httpResponse.StatusCode}"));
                logList.Add($"{Strings.ResponseCode}:{httpResponse.StatusCode}");

                //检查HttpResponse StatusCode
                if (HangfireHttpJobOptions.CheckHttpResponseStatusCode(httpResponse.StatusCode))
                {
                    RunWithTry(() => context.WriteLine($"{Strings.ResponseCode}:{httpResponse.StatusCode} ===> CheckResult: Ok "));
                    logList.Add($"{Strings.ResponseCode}:{httpResponse.StatusCode} ===> CheckResult: Ok ");
                }
                else
                {
                    throw new HttpStatusCodeException(httpResponse.StatusCode);
                }

                RunWithTry(() => context.WriteLine($"{Strings.JobResult}:{result}"));
                logList.Add($"{Strings.JobResult}:{result}");
                RunWithTry(() => context.WriteLine($"{Strings.JobEnd}:{DateTime.Now:yyyy-MM-dd HH:mm:ss}"));
                logList.Add($"{Strings.JobEnd}:{DateTime.Now:yyyy-MM-dd HH:mm:ss}");
                SendSuccessMail(item, string.Join("<br/>", logList));
            }
            catch (Exception ex)
            {
                RunWithTry(() => context.SetTextColor(ConsoleTextColor.Red));
                Logger.ErrorException("HttpJob.Excute=>" + item, ex);
                RunWithTry(() => context.WriteLine(ex.ToString()));
                if (!item.EnableRetry)
                {
                    SendFailMail(item, string.Join("<br/>", logList), ex);
                    AddErrToJob(context, ex);
                    return;
                }
                //获取重试次数
                var count = RunWithTry <string>(() => context.GetJobParameter <string>("RetryCount")) ?? string.Empty;
                if (count == "3")//重试达到三次的时候发邮件通知
                {
                    RunWithTry(() => context.WriteLine(Strings.LimitReached));
                    logList.Add(Strings.LimitReached);
                    SendFailMail(item, string.Join("<br/>", logList), ex);
                    AddErrToJob(context, ex);
                    return;
                }

                context.Items.Add("RetryCount", count);
                throw;
            }
        }
Exemplo n.º 48
0
        private void ProcessJob(
            string jobId,
            IStorageConnection connection, 
            IJobPerformanceProcess process,
            CancellationToken shutdownToken)
        {
            var stateMachine = _context.StateMachineFactory.Create(connection);
            var processingState = new ProcessingState(_context.ServerId, _context.WorkerNumber);

            if (!stateMachine.TryToChangeState(
                jobId,
                processingState,
                new[] { EnqueuedState.StateName, ProcessingState.StateName }))
            {
                return;
            }

            // Checkpoint #3. Job is in the Processing state. However, there are
            // no guarantees that it was performed. We need to re-queue it even
            // it was performed to guarantee that it was performed AT LEAST once.
            // It will be re-queued after the JobTimeout was expired.

            IState state;

            try
            {
                var jobData = connection.GetJobData(jobId);
                jobData.EnsureLoaded();

                var cancellationToken = new ServerJobCancellationToken(
                    jobId, connection, _context, shutdownToken);

                var performContext = new PerformContext(
                    _context, connection, jobId, jobData.Job, jobData.CreatedAt, cancellationToken);

                var latency = (DateTime.UtcNow - jobData.CreatedAt).TotalMilliseconds;
                var duration = Stopwatch.StartNew();

                process.Run(performContext, jobData.Job);
                duration.Stop();

                state = new SucceededState((long) latency, duration.ElapsedMilliseconds);
            }
            catch (OperationCanceledException)
            {
                throw;
            }
            catch (JobPerformanceException ex)
            {
                state = new FailedState(ex.InnerException)
                {
                    Reason = ex.Message
                };
            }
            catch (Exception ex)
            {
                state = new FailedState(ex)
                {
                    Reason = "Internal HangFire Server exception occurred. Please, report it to HangFire developers."
                };
            }

            // Ignore return value, because we should not do
            // anything when current state is not Processing.
            stateMachine.TryToChangeState(jobId, state, new[] { ProcessingState.StateName });
        }
Exemplo n.º 49
0
        public async Task SendMessage(HangfireRecurringScheduledMessageData messageData, PerformContext performContext)
        {
            try
            {
                IPipe <SendContext> sendPipe = CreateMessageContext(messageData, _bus.Address, messageData.JobKey);

                var endpoint = await _bus.GetSendEndpoint(messageData.Destination).ConfigureAwait(false);

                var scheduled = new Scheduled();

                await endpoint.Send(scheduled, sendPipe, performContext.CancellationToken.ShutdownToken).ConfigureAwait(false);

                LogContext.Debug?.Log("Schedule Executed: {JobId}, created at: {CreatedAt}, with range: {StartTime}-{EndTime}", performContext.BackgroundJob.Id,
                                      performContext.BackgroundJob.CreatedAt, messageData.StartTime, messageData.EndTime);
            }
            catch (Exception ex)
            {
                LogContext.Error?.Log(ex, "Failed to send scheduled message: {JobId}, created at: {CreatedAt}, destination: {DestinationAddress}",
                                      performContext.BackgroundJob.Id, messageData.Destination, performContext.BackgroundJob.CreatedAt);

                throw new JobPerformanceException("Job Execution exception", ex);
            }
        }