Add scheduler for master updates

This commit is contained in:
Neo 2020-10-24 05:39:58 +01:00
parent d3dc8cf77d
commit d8b3ffc9c4
5 changed files with 117 additions and 14 deletions

View file

@ -18,5 +18,6 @@ namespace KamihamaWeb.Interfaces
public Dictionary<string, GamedataAsset> EnglishMasterAssets { get; set; }
public Dictionary<string, Dictionary<string, GamedataAsset>> GamedataAssets { get; set; }
public Task<string> ProvideJson(string which);
public Task<bool> RunUpdate();
}
}

View file

@ -180,7 +180,7 @@ namespace KamihamaWeb.Services
public async Task<GamedataAsset> BuildScenarioGeneralJson(GamedataAsset generalAsset, Dictionary<string, GamedataAsset> englishAssets)
{
Log.Information($"Building scenario JSON for {generalAsset.Path}.");
//Log.Information($"Building scenario JSON for {generalAsset.Path}.");
if (!englishAssets.ContainsKey(generalAsset.Path)) // No english to replace with (yet)
{
Log.Warning($"No english asset for {generalAsset.Path}! This should be caught earlier!");
@ -235,7 +235,7 @@ namespace KamihamaWeb.Services
{
if (!en_json.story.ContainsKey(item.Key))
{
Log.Information($"Adding key {item.Key}.");
Log.Debug($"Adding key {item.Key}.");
en_json.story[item.Key] = item.Value;
}
}

View file

@ -59,25 +59,38 @@ namespace KamihamaWeb.Services
"asset_char_list"
};
/// <summary>
/// Update master lists
/// </summary>
/// <returns>Success</returns>
public async Task<bool> UpdateMasterLists()
{
Log.Information("Updating master lists.");
UpdateIsRunning = true;
Log.Information("Fetching current asset version...");
var masterJson = await _rest.GetMasterJson<MasterJsonConfig>(_config["MagiRecoServer:AssetVersion"]);
if (masterJson != null)
{
Log.Information($"Asset version: {masterJson.version}");
AssetsCurrentVersion = masterJson.version;
}
var workGamedataAssets = new Dictionary<string, List<GamedataAsset>>();
foreach (var assetToMod in ModdedAssetLists)
{
Log.Information($"Updating master entry {assetToMod}.json...");
var masterJson = await _rest.GetMasterJson<List<GamedataAsset>>($"{assetToMod}.json.gz");
var json = await _rest.GetMasterJson<List<GamedataAsset>>($"{assetToMod}.json.gz");
if (masterJson == null)
if (json == null)
{
Log.Fatal($"Failed to parse JSON for {assetToMod}, quitting.");
return false;
}
workGamedataAssets.Add(assetToMod, masterJson);
workGamedataAssets.Add(assetToMod, json);
}
Log.Information("Configuring master list...");
@ -202,22 +215,46 @@ namespace KamihamaWeb.Services
public Dictionary<string, GamedataAsset> EnglishMasterAssets { get; set; }
public Dictionary<string, Dictionary<string, GamedataAsset>> GamedataAssets { get; set; }
/// <summary>
/// Is a master data update needed?
/// </summary>
/// <returns>Boolean</returns>
public async Task<bool> IsUpdateRequired()
{
var masterJson = await _rest.GetMasterJson<MasterJsonConfig>(_config["MagiRecoServer:AssetVersion"]);
if (masterJson != null && AssetsCurrentVersion < masterJson.version)
return masterJson != null && AssetsCurrentVersion < masterJson.version;
}
/// <summary>
/// Run update on master data
/// </summary>
/// <returns>Successful</returns>
public async Task<bool> RunUpdate()
{
if (await IsUpdateRequired())
{
return true;
if (!UpdateIsRunning)
{
Log.Information($"Update to master data required. Current version: {AssetsCurrentVersion}.");
try
{
return await UpdateMasterLists();
}
finally
{
Log.Information($"Update finished. New version: {AssetsCurrentVersion}");
}
}
else
{
Log.Information("Skipping update as an update is currently running.");
}
}
else
{
return false;
Log.Information("No update needed.");
}
}
public async Task<bool> RunUpdate()
{
return true;
return false;
}
public async Task<string> ProvideJson(string which)

View file

@ -0,0 +1,28 @@
using System.Threading.Tasks;
using KamihamaWeb.Interfaces;
using Quartz;
using Serilog;
namespace KamihamaWeb.Services
{
public class MasterUpdateJob: IJob
{
private readonly IMasterSingleton _master;
public MasterUpdateJob(IMasterSingleton master)
{
_master = master;
}
public async Task Execute(IJobExecutionContext context)
{
Log.Information("[SCHEDULE] Running MasterUpdateJob (master update).");
if (_master.IsReady)
{
await _master.RunUpdate();
}
else
{
Log.Information("[SCHEDULE] Skipping MasterUpdateJob, service not ready.");
}
}
}
}

View file

@ -12,6 +12,7 @@ using Microsoft.AspNetCore.ResponseCompression;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Quartz;
namespace KamihamaWeb
{
@ -44,10 +45,46 @@ namespace KamihamaWeb
new[] { "application/json" });
});
// Dependencies
services.AddTransient<IRestSharpTransient, RestSharpClient>();
services.AddSingleton<IMasterSingleton, MasterService>();
services.AddSingleton<IDiskCacheSingleton, DiskCacheService>();
services.AddTransient<IMasterListBuilder, MasterListBuilder>();
// Jobs
services.AddTransient<MasterUpdateJob>();
services.AddQuartz(q =>
{
// base quartz scheduler, job and trigger configuration
q.SchedulerId = "Scheduler-Core";
q.UseMicrosoftDependencyInjectionJobFactory(options =>
{
// if we don't have the job in DI, allow fallback
// to configure via default constructor
options.AllowDefaultConstructor = true;
});
var jobKey = new JobKey("Master Update Check", "Master");
q.AddJob<MasterUpdateJob>(jobKey, j => j.WithDescription("Update master asset list if required."));
q.AddTrigger(t => t.WithIdentity("Master Update Check Trigger")
.ForJob(jobKey)
.StartNow()
.WithSimpleSchedule(s => s.
WithInterval(TimeSpan.FromMinutes(2))
.RepeatForever()
)
.WithDescription("Trigger for Master Update Check to update asset list."));
});
// ASP.NET Core hosting
services.AddQuartzServer(options =>
{
// when shutting down we want jobs to complete gracefully
options.WaitForJobsToComplete = true;
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.