/// <summary> /// Creates an instance of DirectoryScanJobModel by inspecting the provided IJobExecutionContext <see cref="IJobExecutionContext"/> /// </summary> /// <param name="context">Content of the job execution <see cref="IJobExecutionContext"/></param> /// <returns>Instance of DirectoryScanJobModel based on the IJobExecutionContext <see cref="IJobExecutionContext"/> passed in</returns> internal static DirectoryScanJobModel GetInstance(IJobExecutionContext context) { JobDataMap mergedJobDataMap = context.MergedJobDataMap; SchedulerContext schedCtxt; try { schedCtxt = context.Scheduler.Context; } catch (SchedulerException e) { throw new JobExecutionException("Error obtaining scheduler context.", e, false); } var model = new DirectoryScanJobModel { DirectoryScanListener = GetListener(mergedJobDataMap, schedCtxt), LastModTime = mergedJobDataMap.ContainsKey(DirectoryScanJob.LastModifiedTime) ? mergedJobDataMap.GetDateTime(DirectoryScanJob.LastModifiedTime) : DateTime.MinValue, MinUpdateAge = mergedJobDataMap.ContainsKey(DirectoryScanJob.MinimumUpdateAge) ? TimeSpan.FromMilliseconds(mergedJobDataMap.GetLong(DirectoryScanJob.MinimumUpdateAge)) : TimeSpan.FromSeconds(5), // default of 5 seconds JobDetailJobDataMap = context.JobDetail.JobDataMap, DirectoriesToScan = GetDirectoriesToScan(schedCtxt, mergedJobDataMap) .Distinct().ToList() }; return(model); }
/// <summary> /// This is the main entry point for job execution. The scheduler will call this method on the /// job once it is triggered. /// </summary> /// <param name="context">The <see cref="IJobExecutionContext"/> that /// the job will use during execution.</param> public Task Execute(IJobExecutionContext context) { DirectoryScanJobModel model = DirectoryScanJobModel.GetInstance(context); List <FileInfo> allFiles = new List <FileInfo>(); List <FileInfo> updatedFiles = new List <FileInfo>(); List <FileInfo> deletedFiles = new List <FileInfo>(); Parallel.ForEach(model.DirectoriesToScan, d => { List <FileInfo> dirAllFiles; List <FileInfo> dirNewOrUpdatedFiles; List <FileInfo> dirDeletedFiles; GetUpdatedOrNewFiles(d, model.LastModTime, model.MaxAgeDate, model.CurrentFileList, out dirAllFiles, out dirNewOrUpdatedFiles, out dirDeletedFiles, model.SearchPattern, model.IncludeSubDirectories); AddToList(updatedFiles, dirNewOrUpdatedFiles); AddToList(deletedFiles, dirDeletedFiles); AddToList(allFiles, dirAllFiles); }); if (updatedFiles.Any() || deletedFiles.Any()) { foreach (var fileInfo in updatedFiles) { log.Info($"Directory '{fileInfo.DirectoryName}' contents updated, notifying listener."); } // notify call back... if (updatedFiles.Any()) { model.DirectoryScanListener.FilesUpdatedOrAdded(updatedFiles); DateTime latestWriteTimeFromFiles = updatedFiles.Select(x => x.LastWriteTime).Max(); model.UpdateLastModifiedDate(latestWriteTimeFromFiles); } if (deletedFiles.Any()) { model.DirectoryScanListener.FilesDeleted(deletedFiles); } //Update current file list model.UpdateFileList(allFiles); } else if (log.IsDebugEnabled()) { foreach (var dir in model.DirectoriesToScan) { log.Debug($"Directory '{dir}' contents unchanged."); } } return(Task.CompletedTask); }
/// <summary> /// This is the main entry point for job execution. The scheduler will call this method on the /// job once it is triggered. /// </summary> /// <param name="context">The <see cref="IJobExecutionContext"/> that /// the job will use during execution.</param> public Task Execute(IJobExecutionContext context) { DirectoryScanJobModel model = DirectoryScanJobModel.GetInstance(context); ConcurrentQueue <FileInfo> updatedFiles = new ConcurrentQueue <FileInfo>(); Parallel.ForEach(model.DirectoriesToScan, d => { var newOrUpdatedFiles = GetUpdatedOrNewFiles(d, model.LastModTime, model.MaxAgeDate); if (newOrUpdatedFiles == null) { return; } foreach (var fileInfo in newOrUpdatedFiles) { updatedFiles.Enqueue(fileInfo); } }); if (updatedFiles.Any()) { foreach (var fileInfo in updatedFiles) { log.Info($"Directory '{fileInfo.DirectoryName}' contents updated, notifying listener."); } // notify call back... model.DirectoryScanListener.FilesUpdatedOrAdded(updatedFiles); DateTime latestWriteTimeFromFiles = updatedFiles.Select(x => x.LastWriteTime).Max(); model.UpdateLastModifiedDate(latestWriteTimeFromFiles); } else if (log.IsDebugEnabled()) { foreach (var dir in model.DirectoriesToScan) { log.Debug($"Directory '{dir}' contents unchanged."); } } return(Task.FromResult(0)); }
/// <summary> /// Creates an instance of DirectoryScanJobModel by inspecting the provided IJobExecutionContext <see cref="IJobExecutionContext"/> /// </summary> /// <param name="context">Content of the job execution <see cref="IJobExecutionContext"/></param> /// <returns>Instance of DirectoryScanJobModel based on the IJobExecutionContext <see cref="IJobExecutionContext"/> passed in</returns> internal static DirectoryScanJobModel GetInstance(IJobExecutionContext context) { JobDataMap mergedJobDataMap = context.MergedJobDataMap; SchedulerContext schedCtxt; try { schedCtxt = context.Scheduler.Context; } catch (SchedulerException e) { throw new JobExecutionException("Error obtaining scheduler context.", e, false); } var model = new DirectoryScanJobModel { DirectoryScanListener = GetListener(mergedJobDataMap, schedCtxt), LastModTime = mergedJobDataMap.ContainsKey(DirectoryScanJob.LastModifiedTime) ? mergedJobDataMap.GetDateTime(DirectoryScanJob.LastModifiedTime) : DateTime.MinValue, MinUpdateAge = mergedJobDataMap.ContainsKey(DirectoryScanJob.MinimumUpdateAge) ? TimeSpan.FromMilliseconds(mergedJobDataMap.GetLong(DirectoryScanJob.MinimumUpdateAge)) : TimeSpan.FromSeconds(5), // default of 5 seconds JobDetailJobDataMap = context.JobDetail.JobDataMap, DirectoriesToScan = GetDirectoriesToScan(schedCtxt, mergedJobDataMap) .Distinct().ToList(), CurrentFileList = mergedJobDataMap.ContainsKey(DirectoryScanJob.CurrentFileList) ? (List <FileInfo>)mergedJobDataMap.Get(DirectoryScanJob.CurrentFileList) : new List <FileInfo>(), SearchPattern = mergedJobDataMap.ContainsKey(DirectoryScanJob.SearchPattern) ? mergedJobDataMap.GetString(DirectoryScanJob.SearchPattern) : "*", IncludeSubDirectories = mergedJobDataMap.ContainsKey(DirectoryScanJob.IncludeSubDirectories) ? mergedJobDataMap.GetBooleanValue(DirectoryScanJob.IncludeSubDirectories) : false }; return(model); }