/// <summary> /// Executes the specified context. /// </summary> /// <param name="context">The context.</param> public void Execute(IJobExecutionContext context) { JobDataMap dataMap = context.JobDetail.JobDataMap; int sqlCommandTimeout = dataMap.GetString(TIMEOUT_KEY).AsIntegerOrNull() ?? 300; StringBuilder results = new StringBuilder(); int updatedDataViewCount = 0; var errors = new List <string>(); List <Exception> exceptions = new List <Exception>(); using (var rockContextList = new RockContext()) { var currentDateTime = RockDateTime.Now; // get a list of all the data views that need to be refreshed var expiredPersistedDataViewIds = new DataViewService(rockContextList).Queryable() .Where(a => a.PersistedScheduleIntervalMinutes.HasValue) .Where(a => (a.PersistedLastRefreshDateTime == null) || (System.Data.Entity.SqlServer.SqlFunctions.DateAdd("mi", a.PersistedScheduleIntervalMinutes.Value, a.PersistedLastRefreshDateTime.Value) < currentDateTime) ) .Select(a => a.Id); var expiredPersistedDataViewsIdsList = expiredPersistedDataViewIds.ToList(); foreach (var dataViewId in expiredPersistedDataViewsIdsList) { using (var persistContext = new RockContext()) { var dataView = new DataViewService(persistContext).Get(dataViewId); var name = dataView.Name; try { context.UpdateLastStatusMessage($"Updating {dataView.Name}"); dataView.PersistResult(sqlCommandTimeout); persistContext.SaveChanges(); updatedDataViewCount++; } catch (Exception ex) { // Capture and log the exception because we're not going to fail this job // unless all the data views fail. var errorMessage = $"An error occurred while trying to update persisted data view '{name}' so it was skipped. Error: {ex.Message}"; errors.Add(errorMessage); var ex2 = new Exception(errorMessage, ex); exceptions.Add(ex2); ExceptionLogService.LogException(ex2, null); continue; } } } } // Format the result message results.AppendLine($"Updated {updatedDataViewCount} {"dataview".PluralizeIf( updatedDataViewCount != 1 )}"); context.Result = results.ToString(); if (errors.Any()) { StringBuilder sb = new StringBuilder(); sb.AppendLine(); sb.Append("Errors: "); errors.ForEach(e => { sb.AppendLine(); sb.Append(e); }); string errorMessage = sb.ToString(); context.Result += errorMessage; // We're not going to throw an aggregate exception unless there were no successes. // Otherwise the status message does not show any of the success messages in // the last status message. if (updatedDataViewCount == 0) { throw new AggregateException(exceptions.ToArray()); } } }