From eb7adc741ad843c46cf0920e61651a7de2151b01 Mon Sep 17 00:00:00 2001 From: TekH Date: Sun, 12 Jul 2026 00:04:00 +0200 Subject: [PATCH] feat: Add Hangfire infrastructure with dynamic storage configuration - Install Hangfire packages (Core, AspNetCore, SqlServer, InMemory) - Configure Hangfire in Program.cs with boolean InMemory flag from appsettings - Add Hangfire dashboard at /hangfire route - Update appsettings.json with Hangfire:InMemory configuration - Update launchSettings.json with new launch URL - Remove obsolete Worker.cs background service --- .../ECMJobRunner.WebCron.csproj | 11 ++++ ECMJobRunner.WebCron/Program.cs | 55 ++++++++++++++++++- .../Properties/launchSettings.json | 6 +- ECMJobRunner.WebCron/Worker.cs | 24 -------- ECMJobRunner.WebCron/appsettings.json | 11 +++- 5 files changed, 78 insertions(+), 29 deletions(-) delete mode 100644 ECMJobRunner.WebCron/Worker.cs diff --git a/ECMJobRunner.WebCron/ECMJobRunner.WebCron.csproj b/ECMJobRunner.WebCron/ECMJobRunner.WebCron.csproj index 5419ef0..3c386f4 100644 --- a/ECMJobRunner.WebCron/ECMJobRunner.WebCron.csproj +++ b/ECMJobRunner.WebCron/ECMJobRunner.WebCron.csproj @@ -7,7 +7,18 @@ + + + + + + + + + + + diff --git a/ECMJobRunner.WebCron/Program.cs b/ECMJobRunner.WebCron/Program.cs index a55475f..a718986 100644 --- a/ECMJobRunner.WebCron/Program.cs +++ b/ECMJobRunner.WebCron/Program.cs @@ -1,10 +1,57 @@ +using ECMJobRunner.Application; +using ECMJobRunner.Infrastructure; using ECMJobRunner.WebCron; +using Hangfire; +using Hangfire.SqlServer; +using Microsoft.Data.SqlClient; var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.AddControllers(); -builder.Services.AddHostedService(); +builder.Services.AddHostedService(); + +// Register services +var cnnStr = builder.Configuration.GetConnectionString("SDD-VMP04-SQL17") + ?? throw new InvalidOperationException("Connection string 'SDD-VMP04-SQL17' not found."); +builder.Services.AddJobRunnerInfrastructure(cnnStr); + +var recClientApiUrl = builder.Configuration.GetValue("ReC:ApiUrl") + ?? throw new InvalidOperationException("ReC:ApiUrl not found."); +builder.Services.AddJobRunnerServices(recClientApiUrl); + +// Get Hangfire storage configuration +var useInMemory = builder.Configuration.GetValue("Hangfire:InMemory"); + +// Add Hangfire services with configurable storage +builder.Services.AddHangfire(configuration => +{ + configuration + .SetDataCompatibilityLevel(CompatibilityLevel.Version_180) + .UseSimpleAssemblyNameTypeSerializer() + .UseRecommendedSerializerSettings(); + + // Configure storage based on appsettings + if (useInMemory) + { + configuration.UseInMemoryStorage(); + } + else // Use SQL Server storage + { + configuration.UseSqlServerStorage(cnnStr, new SqlServerStorageOptions + { + CommandBatchMaxTimeout = TimeSpan.FromMinutes(5), + SlidingInvisibilityTimeout = TimeSpan.FromMinutes(5), + QueuePollInterval = TimeSpan.Zero, + UseRecommendedIsolationLevel = true, + DisableGlobalLocks = true, + SqlClientFactory = SqlClientFactory.Instance + }); + } +}); + +// Add Hangfire server +builder.Services.AddHangfireServer(); builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); @@ -22,6 +69,12 @@ app.UseHttpsRedirection(); app.UseAuthorization(); +// Add Hangfire Dashboard with no authentication (for development) +app.UseHangfireDashboard("/hangfire", new DashboardOptions +{ + Authorization = new[] { new AllowAllDashboardAuthorizationFilter() } +}); + app.MapControllers(); app.Run(); diff --git a/ECMJobRunner.WebCron/Properties/launchSettings.json b/ECMJobRunner.WebCron/Properties/launchSettings.json index 337539e..2d26522 100644 --- a/ECMJobRunner.WebCron/Properties/launchSettings.json +++ b/ECMJobRunner.WebCron/Properties/launchSettings.json @@ -13,7 +13,7 @@ "commandName": "Project", "dotnetRunMessages": true, "launchBrowser": true, - "launchUrl": "swagger", + "launchUrl": "hangfire", "applicationUrl": "http://localhost:5271", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" @@ -23,7 +23,7 @@ "commandName": "Project", "dotnetRunMessages": true, "launchBrowser": true, - "launchUrl": "swagger", + "launchUrl": "hangfire", "applicationUrl": "https://localhost:7027;http://localhost:5271", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" @@ -32,7 +32,7 @@ "IIS Express": { "commandName": "IISExpress", "launchBrowser": true, - "launchUrl": "swagger", + "launchUrl": "hangfire", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } diff --git a/ECMJobRunner.WebCron/Worker.cs b/ECMJobRunner.WebCron/Worker.cs deleted file mode 100644 index 4c1fcec..0000000 --- a/ECMJobRunner.WebCron/Worker.cs +++ /dev/null @@ -1,24 +0,0 @@ -namespace ECMJobRunner.WebCron -{ - public class Worker : BackgroundService - { - private readonly ILogger _logger; - - public Worker(ILogger logger) - { - _logger = logger; - } - - protected override async Task ExecuteAsync(CancellationToken stoppingToken) - { - while (!stoppingToken.IsCancellationRequested) - { - if (_logger.IsEnabled(LogLevel.Information)) - { - _logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now); - } - await Task.Delay(1000, stoppingToken); - } - } - } -} diff --git a/ECMJobRunner.WebCron/appsettings.json b/ECMJobRunner.WebCron/appsettings.json index 10f68b8..c0565e2 100644 --- a/ECMJobRunner.WebCron/appsettings.json +++ b/ECMJobRunner.WebCron/appsettings.json @@ -5,5 +5,14 @@ "Microsoft.AspNetCore": "Warning" } }, - "AllowedHosts": "*" + "ConnectionStrings": { + "SDD-VMP04-SQL17": "Server=SDD-VMP04-SQL17\\DD_DEVELOP01;Database=DD_ECM;User Id=sa;Password=dd;Encrypt=false;TrustServerCertificate=True;" + }, + "AllowedHosts": "*", + "Hangfire": { + "InMemory": true + }, + "ReC": { + "ApiUrl": "http://172.24.12.39:90" + } }