更新Hangfire提取到 框架
This commit is contained in:
1 parent
33ef90a5cc
commit
7c29e57623
11 files changed
+151
-48
No files matched your search
@@ -0,0 +1,49 @@
|
||||
using Hangfire;
|
||||
using MAX.Framework.DependencyInjection;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
|
||||
/// <summary>不连接数据库,检查宿主配置边界及共享服务注册。</summary>
|
||||
internal static class HangfireChecks
|
||||
{
|
||||
public static void Run()
|
||||
{
|
||||
var settings = new Dictionary<string, string?>
|
||||
{
|
||||
["Hangfire:ConnectionString"] = "Server=localhost;Database=hangfire;Uid=test;Pwd=test",
|
||||
["Hangfire:Dashboard:User"] = "test",
|
||||
["Hangfire:Dashboard:Pass"] = "test"
|
||||
};
|
||||
foreach (var key in settings.Keys)
|
||||
{
|
||||
foreach (var missing in new string?[] { null, " " })
|
||||
{
|
||||
var invalid = new Dictionary<string, string?>(settings) { [key] = missing };
|
||||
var services = new ServiceCollection();
|
||||
try
|
||||
{
|
||||
services.AddStoreHangfire(new ConfigurationBuilder().AddInMemoryCollection(invalid).Build());
|
||||
throw new Exception("Expected missing configuration failure: " + key);
|
||||
}
|
||||
catch (InvalidOperationException ex) when (ex.Message.Contains(key)) { }
|
||||
if (services.Count != 0) throw new Exception("Invalid configuration partially registered services");
|
||||
}
|
||||
}
|
||||
|
||||
var valid = new ServiceCollection();
|
||||
valid.AddStoreHangfire(new ConfigurationBuilder().AddInMemoryCollection(settings).Build());
|
||||
if (valid.Count(d => d.ServiceType == typeof(IFreeSql) && Equals(d.ServiceKey, "HangfireConnection")) != 1
|
||||
|| valid.Count(d => d.ServiceType == typeof(JobStorage)) != 1
|
||||
|| valid.Count(d => d.ServiceType == typeof(IHostedService)) != 1
|
||||
|| valid.Count(d => d.ServiceType == typeof(DashboardOptions)) != 1)
|
||||
throw new Exception("Expected one shared storage, worker and dashboard registration");
|
||||
using var provider = valid.BuildServiceProvider();
|
||||
var database = provider.GetRequiredKeyedService<IFreeSql>("HangfireConnection");
|
||||
if (!ReferenceEquals(database, provider.GetRequiredKeyedService<IFreeSql>("HangfireConnection")))
|
||||
throw new Exception("Task database must be a singleton");
|
||||
if (provider.GetRequiredService<DashboardOptions>().Authorization.Count() != 1)
|
||||
throw new Exception("Dashboard authentication missing");
|
||||
Console.WriteLine("PASS Hangfire configuration and shared registrations (no database connection)");
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,7 @@ using Microsoft.AspNetCore.Mvc.ApplicationParts;
|
||||
using Microsoft.AspNetCore.Mvc.Controllers;
|
||||
|
||||
if (args.ElementAtOrDefault(0) == "configuration") { ConfigurationChecks.Run(); return; }
|
||||
if (args.ElementAtOrDefault(0) == "hangfire") { HangfireChecks.Run(); return; }
|
||||
|
||||
// Run each scenario in a fresh process: default ALC intentionally cannot unload plugins.
|
||||
var finderType = typeof(ServiceCollectionExtensions).Assembly.GetType("MAX.Framework.DependencyInjection.StoreAppTypeFinder", true)!;
|
||||
@@ -46,6 +47,8 @@ if (mode is "image" or "plugins")
|
||||
host.Configuration["Search:Url"] = "https://host.invalid";
|
||||
host.Configuration["ImageCache:ConnectionString"] = "host-only";
|
||||
core.Invoke(null, new object[] { host, plugins, new Dictionary<Type, object>() });
|
||||
if (host.Services.Any(d => d.ServiceType == typeof(Hangfire.JobStorage)))
|
||||
throw new Exception("Plugins must not register shared Hangfire storage");
|
||||
using var built = host.Build();
|
||||
var image = built.Services.GetRequiredKeyedService<PluginContext>("ImageCache");
|
||||
if (image.Configuration["ImageCache:ConnectionString"] is null or "host-only") throw new Exception("Image config isolation failed");
|
||||
@@ -56,7 +59,7 @@ if (mode is "image" or "plugins")
|
||||
var cloud = built.Services.GetRequiredKeyedService<PluginContext>("CloudProduct");
|
||||
if (cloud.Configuration["Search:Url"] is null or "https://host.invalid") throw new Exception("Cloud config isolation failed");
|
||||
if (host.Configuration["Search:Url"] != "https://host.invalid") throw new Exception("Cloud modified host configuration");
|
||||
foreach (var name in new[] { "OpenSearchService", "UserFavoritesIndexService", "RawDataStorage", "GoodsIndexJob", "GoodsService" })
|
||||
foreach (var name in new[] { "OpenSearchService", "UserFavoritesIndexService", "RawDataStorage", "GoodsIndexJob", "GoodsViolationIndexJob", "GoodsService" })
|
||||
{
|
||||
var type = plugins.SelectMany(p => p.GetTypes()).Single(t => t.Name == name);
|
||||
using var scope = built.Services.CreateScope();
|
||||
|
||||
Reference in new issue
Block a user