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; }
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; }
internal PerformedContext( PerformContext context, bool canceled, Exception exception) : base(context) { Canceled = canceled; Exception = exception; }
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); }
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); }
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); }
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; } } }
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; }
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; } }
public async Task ProcessResults(PerformContext hangfireContext) { await _carlaSharepoint.ProcessResultsFolders(); }
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()); }
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); } }
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."); }
/// <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); }
internal PerformingContext( PerformContext context) : base(context) { }
/// <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;
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}"); }
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(); }
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)); }
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); }
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)); } }
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); } }
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))); }
public AsyncLocalScope(PerformContext context) => PerformContext.Value = context;
public void InstanceTestJob(PerformContext context) { context.WriteLine($"{DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss")} InstanceTestJob Running ..."); }
public void Execute(TestJobArg arg, PerformContext context) { Console.WriteLine(arg.ToString()); context.WriteLine($" context - {arg} , helper - {_constHelper.Test()}"); }
public static void StaticTestJob(PerformContext context) { Console.WriteLine($"{DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss")} StaticTestJob Running ..."); }
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." }; } }
public static IDisposable InContext(PerformContext context) => new AsyncLocalScope(context);
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; } }
private static void AddErrToJob(PerformContext context, Exception ex) { context.SetJobParameter("jobErr", ex.Message); }
public void Execute(PerformContext context) { // Execute business logic _csvFileHandlerManager.HandleCsvFiles(); }
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." }; } }
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; } }
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 }); }
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); } }