use cache ttl for metadata files
This commit is contained in:
parent
ec3bf67995
commit
64d0b4b35e
@ -9,6 +9,7 @@ public static class DownloadCacheHelper
|
|||||||
{
|
{
|
||||||
private static HttpClient _httpClient = new() { Timeout = TimeSpan.FromMinutes(15) };
|
private static HttpClient _httpClient = new() { Timeout = TimeSpan.FromMinutes(15) };
|
||||||
|
|
||||||
|
public static TimeSpan SuggestedTtl = TimeSpan.FromHours(1);
|
||||||
public static string CachePath = Path.Join(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
|
public static string CachePath = Path.Join(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
|
||||||
"spt-installer/cache");
|
"spt-installer/cache");
|
||||||
|
|
||||||
@ -50,10 +51,10 @@ public static class DownloadCacheHelper
|
|||||||
/// <param name="expectedHash">The expected hash of the file in the cache</param>
|
/// <param name="expectedHash">The expected hash of the file in the cache</param>
|
||||||
/// <param name="cachedFile">The file found in the cache; null if no file is found</param>
|
/// <param name="cachedFile">The file found in the cache; null if no file is found</param>
|
||||||
/// <returns>True if the file is in the cache and its hash matches the expected hash, otherwise false</returns>
|
/// <returns>True if the file is in the cache and its hash matches the expected hash, otherwise false</returns>
|
||||||
public static bool CheckCache(string fileName, string expectedHash, out FileInfo cachedFile)
|
public static bool CheckCacheHash(string fileName, string expectedHash, out FileInfo cachedFile)
|
||||||
=> CheckCache(new FileInfo(Path.Join(CachePath, fileName)), expectedHash, out cachedFile);
|
=> CheckCacheHash(new FileInfo(Path.Join(CachePath, fileName)), expectedHash, out cachedFile);
|
||||||
|
|
||||||
private static bool CheckCache(FileInfo cacheFile, string expectedHash, out FileInfo fileInCache)
|
private static bool CheckCacheHash(FileInfo cacheFile, string expectedHash, out FileInfo fileInCache)
|
||||||
{
|
{
|
||||||
fileInCache = cacheFile;
|
fileInCache = cacheFile;
|
||||||
|
|
||||||
@ -86,6 +87,44 @@ public static class DownloadCacheHelper
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a file in the cache based on a time-to-live from its last modified time
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="fileName">The name of the file to look for in the cache</param>
|
||||||
|
/// <param name="ttl">The time-to-live to check against</param>
|
||||||
|
/// <param name="cachedFile">The file found in the cache if it exists</param>
|
||||||
|
/// <returns>Returns true if the file was found in the cache, otherwise false</returns>
|
||||||
|
public static bool CheckCacheTTL(string fileName, TimeSpan ttl, out FileInfo cachedFile) =>
|
||||||
|
CheckCacheTTL(new FileInfo(Path.Join(CachePath, fileName)), ttl, out cachedFile);
|
||||||
|
|
||||||
|
private static bool CheckCacheTTL(FileInfo cacheFile, TimeSpan ttl, out FileInfo fileInCache)
|
||||||
|
{
|
||||||
|
fileInCache = cacheFile;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
cacheFile.Refresh();
|
||||||
|
Directory.CreateDirectory(CachePath);
|
||||||
|
|
||||||
|
if (!cacheFile.Exists)
|
||||||
|
{
|
||||||
|
Log.Information($"{cacheFile.Name} {(cacheFile.Exists ? "is in cache" : "NOT in cache")}");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var validTimeToLive = cacheFile.LastWriteTime.Add(ttl) > DateTime.Now;
|
||||||
|
|
||||||
|
Log.Information($"{cacheFile.Name} TTL is {(validTimeToLive ? "OK" : "INVALID")}");
|
||||||
|
|
||||||
|
return validTimeToLive;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Log.Error(ex, "Something went wrong during hashing");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Download a file to the cache folder
|
/// Download a file to the cache folder
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -167,6 +206,33 @@ public static class DownloadCacheHelper
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get or download a file using a time to live
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="fileName">The file to get from cache</param>
|
||||||
|
/// <param name="targetLink">The link to use for the download</param>
|
||||||
|
/// <param name="progress">A progress object for reporting download progress</param>
|
||||||
|
/// <param name="timeToLive">The time-to-live to check against in the cache</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static async Task<FileInfo?> GetOrDownloadFileAsync(string fileName, string targetLink,
|
||||||
|
IProgress<double> progress, TimeSpan timeToLive)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (CheckCacheTTL(fileName, timeToLive, out FileInfo cachedFile))
|
||||||
|
{
|
||||||
|
return cachedFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
return await DownloadFileAsync(fileName, targetLink, progress);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Log.Error(ex, $"Error while getting file: {fileName}");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get the file from cache or download it
|
/// Get the file from cache or download it
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -181,7 +247,7 @@ public static class DownloadCacheHelper
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (CheckCache(fileName, expectedHash, out var cacheFile))
|
if (CheckCacheHash(fileName, expectedHash, out var cacheFile))
|
||||||
return cacheFile;
|
return cacheFile;
|
||||||
|
|
||||||
return await DownloadFileAsync(fileName, targetLink, progress);
|
return await DownloadFileAsync(fileName, targetLink, progress);
|
||||||
@ -206,7 +272,7 @@ public static class DownloadCacheHelper
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (CheckCache(fileName, expectedHash, out var cacheFile))
|
if (CheckCacheHash(fileName, expectedHash, out var cacheFile))
|
||||||
return cacheFile;
|
return cacheFile;
|
||||||
|
|
||||||
return await DownloadFileAsync(fileName, fileDownloadStream);
|
return await DownloadFileAsync(fileName, fileDownloadStream);
|
||||||
|
@ -45,7 +45,7 @@ public class DownloadTask : InstallerTaskBase
|
|||||||
{
|
{
|
||||||
SetStatus("Downloading Patcher", "Verifying cached patcher ...", progressStyle: ProgressStyle.Indeterminate);
|
SetStatus("Downloading Patcher", "Verifying cached patcher ...", progressStyle: ProgressStyle.Indeterminate);
|
||||||
|
|
||||||
if (DownloadCacheHelper.CheckCache("patcher", _expectedPatcherHash, out var cacheFile))
|
if (DownloadCacheHelper.CheckCacheHash("patcher", _expectedPatcherHash, out var cacheFile))
|
||||||
{
|
{
|
||||||
_data.PatcherZipInfo = cacheFile;
|
_data.PatcherZipInfo = cacheFile;
|
||||||
Log.Information("Using cached file {fileName} - Hash: {hash}", _data.PatcherZipInfo.Name,
|
Log.Information("Using cached file {fileName} - Hash: {hash}", _data.PatcherZipInfo.Name,
|
||||||
|
@ -25,8 +25,9 @@ public class ReleaseCheckTask : InstallerTaskBase
|
|||||||
|
|
||||||
var progress = new Progress<double>((d) => { SetStatus(null, null, (int)Math.Floor(d)); });
|
var progress = new Progress<double>((d) => { SetStatus(null, null, (int)Math.Floor(d)); });
|
||||||
var akiReleaseInfoFile =
|
var akiReleaseInfoFile =
|
||||||
await DownloadCacheHelper.DownloadFileAsync("release.json", DownloadCacheHelper.ReleaseMirrorUrl,
|
await DownloadCacheHelper.GetOrDownloadFileAsync("release.json", DownloadCacheHelper.ReleaseMirrorUrl,
|
||||||
progress);
|
progress, DownloadCacheHelper.SuggestedTtl);
|
||||||
|
|
||||||
if (akiReleaseInfoFile == null)
|
if (akiReleaseInfoFile == null)
|
||||||
{
|
{
|
||||||
return Result.FromError("Failed to download release metadata");
|
return Result.FromError("Failed to download release metadata");
|
||||||
@ -38,8 +39,8 @@ public class ReleaseCheckTask : InstallerTaskBase
|
|||||||
SetStatus("Checking for Patches", "", null, ProgressStyle.Indeterminate);
|
SetStatus("Checking for Patches", "", null, ProgressStyle.Indeterminate);
|
||||||
|
|
||||||
var akiPatchMirrorsFile =
|
var akiPatchMirrorsFile =
|
||||||
await DownloadCacheHelper.DownloadFileAsync("mirrors.json", DownloadCacheHelper.PatchMirrorUrl,
|
await DownloadCacheHelper.GetOrDownloadFileAsync("mirrors.json", DownloadCacheHelper.PatchMirrorUrl,
|
||||||
progress);
|
progress, DownloadCacheHelper.SuggestedTtl);
|
||||||
|
|
||||||
if (akiPatchMirrorsFile == null)
|
if (akiPatchMirrorsFile == null)
|
||||||
{
|
{
|
||||||
|
@ -140,8 +140,8 @@ public class InstallerUpdateInfo : ReactiveObject
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
var installerInfoFile =
|
var installerInfoFile =
|
||||||
await DownloadCacheHelper.DownloadFileAsync("installer.json", DownloadCacheHelper.InstallerInfoUrl,
|
await DownloadCacheHelper.GetOrDownloadFileAsync("installer.json", DownloadCacheHelper.InstallerInfoUrl, null
|
||||||
null);
|
, DownloadCacheHelper.SuggestedTtl);
|
||||||
|
|
||||||
if (installerInfoFile == null)
|
if (installerInfoFile == null)
|
||||||
{
|
{
|
||||||
|
@ -286,9 +286,11 @@ public class PreChecksViewModel : ViewModelBase
|
|||||||
InstallButtonCheckState = StatusSpinner.SpinnerState.Running;
|
InstallButtonCheckState = StatusSpinner.SpinnerState.Running;
|
||||||
|
|
||||||
var progress = new Progress<double>((d) => { });
|
var progress = new Progress<double>((d) => { });
|
||||||
|
|
||||||
var akiReleaseInfoFile =
|
var akiReleaseInfoFile =
|
||||||
await DownloadCacheHelper.DownloadFileAsync("release.json", DownloadCacheHelper.ReleaseMirrorUrl,
|
await DownloadCacheHelper.GetOrDownloadFileAsync("release.json", DownloadCacheHelper.ReleaseMirrorUrl,
|
||||||
progress);
|
progress, DownloadCacheHelper.SuggestedTtl);
|
||||||
|
|
||||||
if (akiReleaseInfoFile == null)
|
if (akiReleaseInfoFile == null)
|
||||||
{
|
{
|
||||||
InstallButtonText = "Could not get SPT release metadata";
|
InstallButtonText = "Could not get SPT release metadata";
|
||||||
|
Loading…
x
Reference in New Issue
Block a user