diff --git a/.vscode/settings.json b/.vscode/settings.json index 0a66f88..e010ee0 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -18,6 +18,7 @@ "DEVICEHEIGHTPOINTS", "DEVICEWIDTHPOINTS", "endianness", + "Exif", "FAMC", "FAMS", "FIXEDMEDIA", diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 7d0e388..6b33062 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -82,13 +82,16 @@ "problemMatcher": "$msCompile" }, { - "label": "File-Folder-Helper AOT s X Sort", + "label": "File-Folder-Helper AOT s X Day-Helper-2025-03-20", "type": "shell", "command": "L:/DevOps/Mesa_FI/File-Folder-Helper/bin/Release/net8.0/win-x64/publish/File-Folder-Helper.exe", "args": [ "s", "X", - "L:/DevOps/Mesa_FI/File-Watcher' Day-Helper-2024-01-08 'L:/DevOps/Mesa_FI/File-Watcher/Helpers" + "L:/DevOps/Mesa_FI/File-Watcher", + "Day-Helper-2025-03-20", + "false", + "4" ], "problemMatcher": [] } diff --git a/File-Watcher.csproj b/File-Watcher.csproj index 18f5f72..43fcf66 100644 --- a/File-Watcher.csproj +++ b/File-Watcher.csproj @@ -1,4 +1,4 @@ - + enable enable @@ -10,8 +10,9 @@ 6062c774-99a9-4f4a-b42d-a9cb7fcbd8be + - + @@ -19,9 +20,13 @@ - + + + - + + + \ No newline at end of file diff --git a/Helpers/DeterministicHashCodeHelper.cs b/Helpers/DeterministicHashCodeHelper.cs new file mode 100644 index 0000000..05e5f72 --- /dev/null +++ b/Helpers/DeterministicHashCodeHelper.cs @@ -0,0 +1,363 @@ +using CliWrap; +using File_Watcher.Models; +using ShellProgressBar; +using System.Collections.ObjectModel; +using System.Drawing; +using System.Drawing.Imaging; +using System.IO.Compression; +using System.Runtime.InteropServices; +using System.Text.Json; +using View_by_Distance.Metadata.Models; +using View_by_Distance.Metadata.Models.Stateless; +using View_by_Distance.Shared.Models; +using View_by_Distance.Shared.Models.Stateless; + +namespace File_Watcher.Helpers; + +internal static partial class DeterministicHashCodeHelper +{ + + private class Windows : IWindows, IDisposable + { + + private ProgressBar? _ProgressBar; + private readonly ProgressBarOptions _ProgressBarOptions; + + public int CurrentTick { get; internal set; } + + public Windows() => + _ProgressBarOptions = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true }; + + DeterministicHashCode IWindows.GetDeterministicHashCode(HttpClient httpClient, Uri uri) => + GetDeterministicHashCode(httpClient, uri); + + DeterministicHashCode IWindows.GetDeterministicHashCode(HttpClient? httpClient, FilePath filePath) + { + DeterministicHashCode result; + if (httpClient is not null) + result = GetDeterministicHashCode(httpClient, new Uri(filePath.FullName)); + else + { + Stream stream = File.OpenRead(filePath.FullName); + result = GetDeterministicHashCode(stream); + stream.Dispose(); + } + return result; + } + + private static DeterministicHashCode GetDeterministicHashCode(HttpClient httpClient, Uri uri) + { + DeterministicHashCode result; + Stream stream = GetStream(httpClient, uri); + result = GetDeterministicHashCode(stream); + stream.Dispose(); + return result; + } + + private static Stream GetStream(HttpClient httpClient, Uri uri) + { + Stream result; + Task task = httpClient.GetStreamAsync(uri); + task.Wait(); + result = task.Result; + return result; + } + + private static DeterministicHashCode GetDeterministicHashCode(Stream stream) + { + DeterministicHashCode result; + int? id; + int? width; + int? height; + try + { +#pragma warning disable CA1416 + using Image image = Image.FromStream(stream); + width = image.Width; + height = image.Height; + using Bitmap bitmap = new(image); + Rectangle rectangle = new(0, 0, image.Width, image.Height); + BitmapData bitmapData = bitmap.LockBits(rectangle, ImageLockMode.ReadOnly, bitmap.PixelFormat); + IntPtr intPtr = bitmapData.Scan0; + int length = bitmapData.Stride * bitmap.Height; + byte[] bytes = new byte[length]; + Marshal.Copy(intPtr, bytes, 0, length); + bitmap.UnlockBits(bitmapData); +#pragma warning restore CA1416 + id = IId.GetDeterministicHashCode(bytes); + } + catch (Exception) + { + id = null; + width = null; + height = null; + } + result = new(height, id, width); + return result; + } + + void IWindows.Tick() => + _ProgressBar?.Tick(); + + void IDisposable.Dispose() + { + _ProgressBar?.Dispose(); + GC.SuppressFinalize(this); + } + + void IWindows.ConstructProgressBar(int maxTicks, string message) + { + _ProgressBar?.Dispose(); + _ProgressBar = new(maxTicks, message, _ProgressBarOptions); + } + + ReadOnlyCollection IWindows.ConvertAndGetFastForwardMovingPictureExpertsGroupFiles(ResultSettings resultSettings, HttpClient? httpClient, FilePath filePath) + { + List results = []; + bool isValidVideoFormatExtensions = resultSettings.ValidVideoFormatExtensions.Contains(filePath.ExtensionLowered); + if (isValidVideoFormatExtensions) + { + bool check; + if (httpClient is not null) + DownloadFile(httpClient, filePath); + try + { + CommandTask commandTask = Cli.Wrap("L:/Git/ffmpeg-2024-10-02-git-358fdf3083-full_build/bin/ffmpeg.exe") + .WithArguments(["-i", filePath.FullName, "-vf", "select=eq(n\\,0)", "-q:v", "1", $"{filePath.Name}-%4d.jpg"]) + .WithWorkingDirectory(filePath.DirectoryFullPath) + .ExecuteAsync(); + commandTask.Task.Wait(); + check = true; + } + catch (Exception) + { + check = false; + } + if (check) + { + results.AddRange(Directory.GetFiles(filePath.DirectoryFullPath, $"{filePath.Name}-*.jpg", SearchOption.TopDirectoryOnly)); + if (results.Count == 0) + throw new Exception(); + File.SetCreationTime(results[0], new(filePath.CreationTicks)); + File.SetLastWriteTime(results[0], new(filePath.LastWriteTicks)); + Thread.Sleep(100); + } + } + return results.AsReadOnly(); + } + + private static void DownloadFile(HttpClient httpClient, FilePath filePath) + { + FileStream fileStream = new(filePath.FullName, FileMode.Truncate); + Task httpResponseMessage = httpClient.GetAsync(filePath.FullName); + httpResponseMessage.Wait(); + Task task = httpResponseMessage.Result.Content.CopyToAsync(fileStream); + task.Wait(); + } + + } + + internal static bool WindowsWork(AppSettings appSettings, ILogger? logger) + { + string json; + string jsonFile; + string sourceDirectory; + List check = []; + string archiveEntryFile; + long ticks = DateTime.Now.Ticks; + ReadOnlyCollection collection; + string rootDirectory = Path.GetFullPath(appSettings.ResultSettings.RootDirectory); + if (!Directory.Exists(rootDirectory)) + _ = Directory.CreateDirectory(rootDirectory); + string[] zipFiles = Directory.GetFiles(rootDirectory, "*.zip", SearchOption.TopDirectoryOnly); + if (zipFiles.Length > 0) + _ = IPath.DeleteEmptyDirectories(rootDirectory); + foreach (string zipFile in zipFiles) + { + check.Clear(); + sourceDirectory = zipFile[..^4]; + jsonFile = $"{sourceDirectory}.json"; + if (Directory.Exists(sourceDirectory) || File.Exists(jsonFile)) + continue; + _ = Directory.CreateDirectory(sourceDirectory); + using ZipArchive zip = ZipFile.Open(zipFile, ZipArchiveMode.Read); + foreach (ZipArchiveEntry zipArchiveEntry in zip.Entries) + { + check.Add(zipArchiveEntry.Name); + archiveEntryFile = Path.Combine(sourceDirectory, zipArchiveEntry.Name); + zipArchiveEntry.ExtractToFile(archiveEntryFile); + } + collection = WindowsWork(logger, appSettings, ticks, sourceDirectory); + if (check.Count == collection.Count) + { + json = JsonSerializer.Serialize(collection.ToList(), FirstPassCollectionSourceGenerationContext.Default.ListFirstPass); + File.WriteAllText(jsonFile, json); + } + Directory.Delete(sourceDirectory, recursive: true); + } + return true; + } + + private static ReadOnlyCollection WindowsWork(ILogger? logger, AppSettings appSettings, long ticks, string sourceDirectory) + { + ReadOnlyCollection results; + Windows windows = new(); + IWindows windowsInterface = windows; + logger?.LogInformation("{Ticks} {RootDirectory}", ticks, sourceDirectory); + A_Metadata metadata = new(appSettings.ResultSettings, appSettings.MetadataSettings); + int appSettingsMaxDegreeOfParallelism = appSettings.DeterministicHashCodeConfiguration.MaxDegreeOfParallelism; + ReadOnlyCollection files = Directory.GetFiles(sourceDirectory, "*", SearchOption.AllDirectories).AsReadOnly(); + if (files.Count > 0) + _ = IPath.DeleteEmptyDirectories(sourceDirectory); + int filesCount = appSettingsMaxDegreeOfParallelism == 1 ? files.Count : 123000; + windowsInterface.ConstructProgressBar(filesCount, "EnumerateFiles load"); + if (appSettingsMaxDegreeOfParallelism == 1) + results = WindowsSynchronousWork(logger, appSettings, windowsInterface, files, metadata); + else + results = WindowsAsynchronousWork(appSettings, windows, files, metadata, appSettingsMaxDegreeOfParallelism); + return results; + } + + private static ReadOnlyCollection WindowsSynchronousWork(ILogger? logger, AppSettings appSettings, IWindows windows, IEnumerable files, A_Metadata metadata) + { + List results = []; + int index = -1; + ReadOnlyDictionary> keyValuePairs = IMetadata.GetKeyValuePairs(files); + foreach (KeyValuePair> keyValuePair in keyValuePairs) + { + if (keyValuePair.Value.Count > 2) + throw new NotSupportedException("Too many sidecar files!"); + index = WindowsSynchronousWork(logger, appSettings, windows, metadata, results, index, keyValuePair); + } + return results.AsReadOnly(); + } + + private static int WindowsSynchronousWork(ILogger? logger, AppSettings appSettings, IWindows windows, A_Metadata metadata, List results, int index, KeyValuePair> keyValuePair) + { + int result = index + 1; + windows.Tick(); + FilePath filePath; + FirstPass firstPass; + string directoryName; + ExifDirectory exifDirectory; + HttpClient? httpClient = null; + List sidecarFiles; + DeterministicHashCode deterministicHashCode; + bool fastForwardMovingPictureExpertsGroupUsed; + MinimumYearAndPathCombined minimumYearAndPathCombined; + FilePath? fastForwardMovingPictureExpertsGroupFilePath; + ReadOnlyCollection? fastForwardMovingPictureExpertsGroupFiles; + foreach (FileHolder fileHolder in keyValuePair.Value) + { + if (appSettings.DeterministicHashCodeConfiguration.SidecarExtensions.Contains(fileHolder.ExtensionLowered)) + continue; + if (appSettings.ResultSettings.IgnoreExtensions.Contains(fileHolder.ExtensionLowered)) + continue; + filePath = FilePath.Get(appSettings.ResultSettings, appSettings.MetadataSettings, fileHolder, result); + if (filePath.Id is not null && (filePath.IsIntelligentIdFormat || filePath.SortOrder is not null)) + continue; + if (filePath.Id is not null) + { + fastForwardMovingPictureExpertsGroupFiles = null; + deterministicHashCode = new(null, filePath.Id, null); + directoryName = Path.GetFileName(filePath.DirectoryFullPath); + if (directoryName.EndsWith(filePath.Id.Value.ToString())) + continue; + } + else + { + fastForwardMovingPictureExpertsGroupFiles = windows.ConvertAndGetFastForwardMovingPictureExpertsGroupFiles(appSettings.ResultSettings, httpClient, filePath); + fastForwardMovingPictureExpertsGroupFilePath = fastForwardMovingPictureExpertsGroupFiles.Count == 0 ? null : FilePath.Get(appSettings.ResultSettings, appSettings.MetadataSettings, FileHolder.Get(fastForwardMovingPictureExpertsGroupFiles[0]), result); + deterministicHashCode = fastForwardMovingPictureExpertsGroupFilePath is null ? windows.GetDeterministicHashCode(httpClient, filePath) : windows.GetDeterministicHashCode(httpClient, fastForwardMovingPictureExpertsGroupFilePath); + } + sidecarFiles = []; + filePath = FilePath.Get(filePath, deterministicHashCode); + for (int i = 0; i < keyValuePair.Value.Count; i++) + { + if (keyValuePair.Value[i].ExtensionLowered == fileHolder.ExtensionLowered) + continue; + sidecarFiles.Add(keyValuePair.Value[i]); + } + try + { (minimumYearAndPathCombined, exifDirectory) = metadata.GetMetadataCollection(appSettings.ResultSettings, appSettings.MetadataSettings, httpClient, filePath); } + catch (Exception) + { + logger?.LogWarning("<{filePath}>", filePath.FullName); + continue; + } + fastForwardMovingPictureExpertsGroupUsed = fastForwardMovingPictureExpertsGroupFiles is not null && fastForwardMovingPictureExpertsGroupFiles.Count > 0; + if (fastForwardMovingPictureExpertsGroupUsed && fastForwardMovingPictureExpertsGroupFiles is not null) + { + foreach (string fastForwardMovingPictureExpertsGroupFile in fastForwardMovingPictureExpertsGroupFiles) + File.Delete(fastForwardMovingPictureExpertsGroupFile); + } + if (!fastForwardMovingPictureExpertsGroupUsed && appSettings.ResultSettings.ValidVideoFormatExtensions.Contains(filePath.ExtensionLowered)) + fastForwardMovingPictureExpertsGroupUsed = true; + firstPass = new(exifDirectory, fastForwardMovingPictureExpertsGroupUsed, minimumYearAndPathCombined, sidecarFiles.ToArray()); + results.Add(firstPass); + } + return result; + } + + private static ReadOnlyCollection WindowsAsynchronousWork(AppSettings appSettings, Windows windows, ReadOnlyCollection files, A_Metadata metadata, int appSettingsMaxDegreeOfParallelism) + { + List results = []; + FirstPass firstPass; + List distinct = []; + List metadataGroups = []; + ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = appSettingsMaxDegreeOfParallelism }; + files.AsParallel().ForAll(IMetadata.SetExifDirectoryCollection(windows, appSettings.ResultSettings, appSettings.MetadataSettings, metadata, distinct, metadataGroups)); + if (windows?.CurrentTick != results.Count) + throw new NotSupportedException(); + foreach (MetadataGroup metadataGroup in metadataGroups) + { + if (metadataGroup.FastForwardMovingPictureExpertsGroupUsed || !appSettings.ResultSettings.ValidVideoFormatExtensions.Contains(metadataGroup.FilePath.ExtensionLowered)) + firstPass = new(metadataGroup.ExifDirectory, metadataGroup.FastForwardMovingPictureExpertsGroupUsed, metadataGroup.MinimumYearAndPathCombined, metadataGroup.SidecarFiles.ToArray()); + else + firstPass = new(metadataGroup.ExifDirectory, FastForwardMovingPictureExpertsGroupUsed: true, metadataGroup.MinimumYearAndPathCombined, metadataGroup.SidecarFiles.ToArray()); + results.Add(firstPass); + } + return results.AsReadOnly(); + } + + private static ReadOnlyCollection? GetRecursiveCollection(HttpClient httpClient, string host, string page) + { + List? results; + Uri uri = new($"http://{host}/{page}"); + string format = NginxFileSystem.GetFormat(); + TimeZoneInfo timeZoneInfo = TimeZoneInfo.Local; + Task taskHttpResponseMessage = httpClient.GetAsync(uri); + taskHttpResponseMessage.Wait(); + if (!taskHttpResponseMessage.Result.IsSuccessStatusCode) + results = null; + else + { + Task taskString = taskHttpResponseMessage.Result.Content.ReadAsStringAsync(); + taskString.Wait(); + NginxFileSystem[]? nginxFileSystems = JsonSerializer.Deserialize(taskString.Result, NginxFileSystemCollectionSourceGenerationContext.Default.NginxFileSystemArray); + if (nginxFileSystems is null) + results = null; + else + { + results = []; + NginxFileSystem nginxFileSystem; + ReadOnlyCollection? directory; + for (int i = 0; i < nginxFileSystems.Length; i++) + { + nginxFileSystem = NginxFileSystem.Get(format, timeZoneInfo, uri, nginxFileSystems[i]); + if (nginxFileSystem.Type == "file") + results.Add(nginxFileSystem); + else + { + directory = GetRecursiveCollection(httpClient, host, $"{page}/{nginxFileSystem.Name}"); + if (directory is null) + continue; + results.AddRange(directory); + } + } + } + } + return results?.AsReadOnly(); + } + +} \ No newline at end of file diff --git a/Models/AppSettings.cs b/Models/AppSettings.cs index b4db9f3..781e502 100644 --- a/Models/AppSettings.cs +++ b/Models/AppSettings.cs @@ -1,47 +1,45 @@ using System.Text.Json; using System.Text.Json.Serialization; +using View_by_Distance.Shared.Models; namespace File_Watcher.Models; public record AppSettings(CamstarOracleConfiguration CamstarOracleConfiguration, CompassConfiguration CompassConfiguration, + DeterministicHashCodeConfiguration DeterministicHashCodeConfiguration, DriveConfiguration DriveConfiguration, EAFLogConfiguration EAFLogConfiguration, EDADatabaseConfiguration EDADatabaseConfiguration, FileWatcherConfiguration FileWatcherConfiguration, InfinityQSConfiguration InfinityQSConfiguration, IsoConfiguration IsoConfiguration, + MetadataSettings MetadataSettings, MetrologyConfiguration MetrologyConfiguration, NugetConfiguration NugetConfiguration, + ResultSettings ResultSettings, SerialConfiguration SerialConfiguration, StratusConfiguration StratusConfiguration, TransmissionControlProtocolConfiguration TransmissionControlProtocolConfiguration, WaferCounterConfiguration WaferCounterConfiguration) { - public override string ToString() - { - string result = JsonSerializer.Serialize(this, AppSettingsSourceGenerationContext.Default.AppSettings); - return result; - } - - private static void Verify(AppSettings _) - { } - public static AppSettings Get(IConfigurationRoot configurationRoot) { AppSettings result; #pragma warning disable IL3050, IL2026 CamstarOracleConfiguration? camstarOracleConfiguration = configurationRoot.GetSection(nameof(CamstarOracleConfiguration)).Get(); CompassConfiguration? compassConfiguration = configurationRoot.GetSection(nameof(CompassConfiguration)).Get(); + DeterministicHashCodeConfiguration? deterministicHashCodeConfiguration = configurationRoot.GetSection(nameof(DeterministicHashCodeConfiguration)).Get(); DriveConfiguration? driveConfiguration = configurationRoot.GetSection(nameof(DriveConfiguration)).Get(); EAFLogConfiguration? eafLogConfiguration = configurationRoot.GetSection(nameof(EAFLogConfiguration)).Get(); EDADatabaseConfiguration? edaDatabaseConfiguration = configurationRoot.GetSection(nameof(EDADatabaseConfiguration)).Get(); FileWatcherConfiguration? fileWatcherConfiguration = configurationRoot.GetSection(nameof(FileWatcherConfiguration)).Get(); InfinityQSConfiguration? infinityQSConfiguration = configurationRoot.GetSection(nameof(InfinityQSConfiguration)).Get(); IsoConfiguration? isoConfiguration = configurationRoot.GetSection(nameof(IsoConfiguration)).Get(); + MetadataSettings? metadataSettings = configurationRoot.GetSection(nameof(MetadataSettings)).Get(); MetrologyConfiguration? metrologyConfiguration = configurationRoot.GetSection(nameof(MetrologyConfiguration)).Get(); NugetConfiguration? nugetConfiguration = configurationRoot.GetSection(nameof(NugetConfiguration)).Get(); + ResultSettings? resultSettings = configurationRoot.GetSection(nameof(ResultSettings)).Get(); SerialConfiguration? serialConfiguration = configurationRoot.GetSection(nameof(SerialConfiguration)).Get(); StratusConfiguration? stratusConfiguration = configurationRoot.GetSection(nameof(StratusConfiguration)).Get(); TransmissionControlProtocolConfiguration? transmissionControlProtocolConfiguration = configurationRoot.GetSection(nameof(TransmissionControlProtocolConfiguration)).Get(); @@ -49,14 +47,17 @@ public record AppSettings(CamstarOracleConfiguration CamstarOracleConfiguration, #pragma warning restore IL3050, IL2026 if (camstarOracleConfiguration is null || compassConfiguration is null + || deterministicHashCodeConfiguration is null || driveConfiguration is null || eafLogConfiguration is null || edaDatabaseConfiguration is null || fileWatcherConfiguration is null || infinityQSConfiguration is null || isoConfiguration is null + || metadataSettings is null || metrologyConfiguration is null || nugetConfiguration is null + || resultSettings is null || serialConfiguration is null || stratusConfiguration is null || transmissionControlProtocolConfiguration is null @@ -76,14 +77,17 @@ public record AppSettings(CamstarOracleConfiguration CamstarOracleConfiguration, } result = new(camstarOracleConfiguration, compassConfiguration, + deterministicHashCodeConfiguration, driveConfiguration, eafLogConfiguration, edaDatabaseConfiguration, fileWatcherConfiguration, infinityQSConfiguration, isoConfiguration, + metadataSettings, metrologyConfiguration, nugetConfiguration, + resultSettings, serialConfiguration, stratusConfiguration, transmissionControlProtocolConfiguration, @@ -92,6 +96,18 @@ public record AppSettings(CamstarOracleConfiguration CamstarOracleConfiguration, return result; } + private static void Verify(AppSettings appSettings) + { + if (appSettings.DeterministicHashCodeConfiguration.MaxDegreeOfParallelism > Environment.ProcessorCount) + throw new Exception($"Environment.ProcessorCount must be larger or equal to {nameof(appSettings.DeterministicHashCodeConfiguration.MaxDegreeOfParallelism)}"); + } + + public override string ToString() + { + string result = JsonSerializer.Serialize(this, AppSettingsSourceGenerationContext.Default.AppSettings); + return result; + } + } [JsonSourceGenerationOptions(WriteIndented = true)] diff --git a/Models/DeterministicHashCodeConfiguration.cs b/Models/DeterministicHashCodeConfiguration.cs new file mode 100644 index 0000000..45fb036 --- /dev/null +++ b/Models/DeterministicHashCodeConfiguration.cs @@ -0,0 +1,22 @@ +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace File_Watcher.Models; + +public record DeterministicHashCodeConfiguration(int MaxDegreeOfParallelism, + string[] SidecarExtensions) +{ + + public override string ToString() + { + string result = JsonSerializer.Serialize(this, DeterministicHashCodeConfigurationSourceGenerationContext.Default.DeterministicHashCodeConfiguration); + return result; + } + +} + +[JsonSourceGenerationOptions(WriteIndented = true)] +[JsonSerializable(typeof(DeterministicHashCodeConfiguration))] +internal partial class DeterministicHashCodeConfigurationSourceGenerationContext : JsonSerializerContext +{ +} \ No newline at end of file diff --git a/Worker.cs b/Worker.cs index e2c20b0..6f6c887 100644 --- a/Worker.cs +++ b/Worker.cs @@ -1,4 +1,4 @@ -using File_Watcher.Models; +using File_Watcher.Models; using Microsoft.Extensions.Hosting.WindowsServices; using System.Data; @@ -13,13 +13,6 @@ public partial class Worker : BackgroundService private readonly AppSettings _AppSettings; private readonly IHttpClientFactory _HttpClientFactory; - public override Task StopAsync(CancellationToken cancellationToken) - { - if (_AppSettings.FileWatcherConfiguration.Helper == nameof(Helpers.HelperCamstarOracle)) - Helpers.HelperCamstarOracle.Heartbeat(_AppSettings, _HttpClientFactory, _Logger, Infineon.Monitoring.MonA.State.Down, cancellationToken); - return base.StopAsync(cancellationToken); - } - public Worker(IHttpClientFactory httpClientFactory, ILogger logger, IServiceProvider serviceProvider, AppSettings appSettings, List collection) { _Logger = logger; @@ -33,6 +26,37 @@ public partial class Worker : BackgroundService _IsWindowsService = collection.Contains(nameof(WindowsServiceLifetime)); } + public override Task StopAsync(CancellationToken cancellationToken) + { + if (_AppSettings.FileWatcherConfiguration.Helper == nameof(Helpers.HelperCamstarOracle)) + Helpers.HelperCamstarOracle.Heartbeat(_AppSettings, _HttpClientFactory, _Logger, Infineon.Monitoring.MonA.State.Down, cancellationToken); + return base.StopAsync(cancellationToken); + } + + protected override async Task ExecuteAsync(CancellationToken cancellationToken) => + await Body(cancellationToken); + private async Task Body(CancellationToken cancellationToken) + { + if (!_IsWindowsService) + { + _Logger.LogInformation("Set break point and skip to run {_AppSettings.FileWatcherConfiguration.Helper}!", _AppSettings.FileWatcherConfiguration.Helper); + throw new EvaluateException($"Set break point and skip to run {_AppSettings.FileWatcherConfiguration.Helper}!"); + } + if (!_IsWindowsService) + { + for (int i = 0; i < int.MaxValue; i++) + { + BodyInner(cancellationToken); + Thread.Sleep(_AppSettings.FileWatcherConfiguration.MillisecondsDelay); + } + } + while (_IsWindowsService && !cancellationToken.IsCancellationRequested) + { + BodyInner(cancellationToken); + await Task.Delay(_AppSettings.FileWatcherConfiguration.MillisecondsDelay, cancellationToken); + } + } + private void BodyInner(CancellationToken cancellationToken) { _Logger.LogInformation("A) Next execute will be at {date}", DateTime.Now.AddMilliseconds(_AppSettings.FileWatcherConfiguration.MillisecondsDelay).ToString("yyyy-MM-dd hh:mm:ss.fff tt")); @@ -60,6 +84,7 @@ public partial class Worker : BackgroundService nameof(Helpers.HelperSerial) => Helpers.HelperSerial.ReadWrite(_AppSettings, _Logger, cancellationToken), nameof(Helpers.HelperMetrologyFiles) => Helpers.HelperMetrologyFiles.SortAndDelete(_AppSettings, _Logger), nameof(Helpers.HelperCamstarOracle) => Helpers.HelperCamstarOracle.Check(_AppSettings, _Logger, cancellationToken), + nameof(Helpers.DeterministicHashCodeHelper) => Helpers.DeterministicHashCodeHelper.WindowsWork(_AppSettings, _Logger), nameof(Helpers.HelperEDADatabase) => Helpers.HelperEDADatabase.SaveDataCollectionPlans(_AppSettings, _Logger, cancellationToken), _ => throw new NotSupportedException() }; @@ -67,28 +92,4 @@ public partial class Worker : BackgroundService _Logger.LogInformation("B) Next execute will be at {date}", DateTime.Now.AddMilliseconds(_AppSettings.FileWatcherConfiguration.MillisecondsDelay).ToString("yyyy-MM-dd hh:mm:ss.fff tt")); } - private async Task Body(CancellationToken cancellationToken) - { - if (!_IsWindowsService) - { - _Logger.LogInformation("Set break point and skip to run {_AppSettings.FileWatcherConfiguration.Helper}!", _AppSettings.FileWatcherConfiguration.Helper); - throw new EvaluateException($"Set break point and skip to run {_AppSettings.FileWatcherConfiguration.Helper}!"); - } - if (!_IsWindowsService) - { - for (int i = 0; i < int.MaxValue; i++) - { - BodyInner(cancellationToken); - Thread.Sleep(_AppSettings.FileWatcherConfiguration.MillisecondsDelay); - } - } - while (_IsWindowsService && !cancellationToken.IsCancellationRequested) - { - BodyInner(cancellationToken); - await Task.Delay(_AppSettings.FileWatcherConfiguration.MillisecondsDelay, cancellationToken); - } - } - - protected override async Task ExecuteAsync(CancellationToken cancellationToken) => - await Body(cancellationToken); } \ No newline at end of file