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
This commit is contained in:
@@ -7,7 +7,18 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Hangfire.AspNetCore" Version="1.8.23" />
|
||||
<PackageReference Include="Hangfire.Core" Version="1.8.23" />
|
||||
<PackageReference Include="Hangfire.InMemory" Version="1.0.0" />
|
||||
<PackageReference Include="Hangfire.SqlServer" Version="1.8.23" />
|
||||
<PackageReference Include="Microsoft.Data.SqlClient" Version="7.0.2" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.6.2" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\ECMJobRunner.Application\ECMJobRunner.Application.csproj" />
|
||||
<ProjectReference Include="..\ECMJobRunner.Domain\ECMJobRunner.Domain.csproj" />
|
||||
<ProjectReference Include="..\ECMJobRunner.Infrastructure\ECMJobRunner.Infrastructure.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -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<Worker>();
|
||||
builder.Services.AddHostedService<ProfileManager>();
|
||||
|
||||
// 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<string>("ReC:ApiUrl")
|
||||
?? throw new InvalidOperationException("ReC:ApiUrl not found.");
|
||||
builder.Services.AddJobRunnerServices(recClientApiUrl);
|
||||
|
||||
// Get Hangfire storage configuration
|
||||
var useInMemory = builder.Configuration.GetValue<bool>("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();
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
namespace ECMJobRunner.WebCron
|
||||
{
|
||||
public class Worker : BackgroundService
|
||||
{
|
||||
private readonly ILogger<Worker> _logger;
|
||||
|
||||
public Worker(ILogger<Worker> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user