Skip to content

Commit

Permalink
refactor: add support for cancellation tokens in more places
Browse files Browse the repository at this point in the history
  • Loading branch information
anna-is-cute committed Aug 23, 2024
1 parent 8a82fe0 commit ebd9f52
Show file tree
Hide file tree
Showing 15 changed files with 129 additions and 124 deletions.
1 change: 1 addition & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ trim_trailing_whitespace = true
quote_type = single

dotnet_diagnostic.IDE0005.severity = error
dotnet_diagnostic.CA2016.severity = error
6 changes: 3 additions & 3 deletions DownloadTask.cs
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ private async Task Run() {

// refresh the manager package list after install finishes
using (this.Transaction?.StartChild(nameof(this.Plugin.State.UpdatePackages))) {
await this.Plugin.State.UpdatePackages();
await this.Plugin.State.UpdatePackages(this.CancellationToken.Token);
}
} catch (Exception ex) when (ex is TaskCanceledException or OperationCanceledException) {
this.State = State.Cancelled;
Expand Down Expand Up @@ -1067,7 +1067,7 @@ private async Task<List<ModGroup>> ConstructGroups(IDownloadTask_GetVersion info
var oldGroups = new List<ModGroup>();
foreach (var existing in existingGroups) {
try {
var text = await FileHelper.ReadAllTextAsync(existing);
var text = await FileHelper.ReadAllTextAsync(existing, this.CancellationToken.Token);
ModGroup? group;
try {
group = JsonConvert.DeserializeObject<StandardModGroup>(text);
Expand Down Expand Up @@ -1318,7 +1318,7 @@ private async Task<List<ModGroup>> ConstructGroups(IDownloadTask_GetVersion info
});

var oldVersion = "???";
var installedPkgs = await this.Plugin.State.GetInstalled();
var installedPkgs = await this.Plugin.State.GetInstalled(this.CancellationToken.Token);
if (installedPkgs.TryGetValue(info.Variant.Package.Id, out var meta)) {
var variant = meta.Variants.Find(v => v.VariantId == info.Variant.Id);
if (variant != null) {
Expand Down
20 changes: 10 additions & 10 deletions ImportTask.cs
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ internal void Continue() {
});
}

private async Task<Dictionary<string, List<string>>> Hash() {
private async Task<Dictionary<string, List<string>>> Hash(CancellationToken token = default) {
this.StateCurrent = this.StateMax = 0;

if (!this.Plugin.Penumbra.TryGetModDirectory(out this._penumbraPath)) {
Expand All @@ -106,7 +106,7 @@ private async Task<Dictionary<string, List<string>>> Hash() {
var tasks = Directory.EnumerateFiles(this._fullDirectory, "*", SearchOption.AllDirectories)
// ReSharper disable once AccessToDisposedClosure
// disposed after this task has completed, so it's fine
.Select(filePath => this.HashFile(semaphore, filePath));
.Select(filePath => this.HashFile(semaphore, filePath, token));

var rawHashes = await Task.WhenAll(tasks);
return rawHashes
Expand All @@ -117,25 +117,25 @@ private async Task<Dictionary<string, List<string>>> Hash() {
);
}

private async Task<(string hash, string filePath)> HashFile(SemaphoreSlim semaphore, string filePath) {
using var guard = await SemaphoreGuard.WaitAsync(semaphore);
private async Task<(string hash, string filePath)> HashFile(SemaphoreSlim semaphore, string filePath, CancellationToken token = default) {
using var guard = await SemaphoreGuard.WaitAsync(semaphore, token);

using var hasher = new Blake3HashAlgorithm();
hasher.Initialize();

await using var file = FileHelper.OpenRead(filePath);
var hashBytes = await hasher.ComputeHashAsync(file);
var hashBytes = await hasher.ComputeHashAsync(file, token);
var hash = Base64.Url.Encode(hashBytes);

this.StateCurrent += 1;

return (hash, filePath);
}

private async Task<FileList> GetFiles() {
private async Task<FileList> GetFiles(CancellationToken token = default) {
this.StateCurrent = this.StateMax = 0;

var result = await Plugin.GraphQl.Importer.ExecuteAsync(this.VersionId, this.DownloadKey);
var result = await Plugin.GraphQl.Importer.ExecuteAsync(this.VersionId, this.DownloadKey, token);
result.EnsureNoErrors();

var files = result.Data?.GetVersion?.NeededFiles.Files ?? throw new MissingVersionException(this.VersionId);
Expand All @@ -145,7 +145,7 @@ private async Task<FileList> GetFiles() {
// them

var filtered = new FileList {
Files = new Dictionary<string, List<List<string?>>>(),
Files = [],
};

foreach (var (hash, list) in files.Files) {
Expand Down Expand Up @@ -249,7 +249,7 @@ private void Delete() {
this.Plugin.Penumbra.CopyModSettings(this.DirectoryName, Path.GetFileName(this._fullDirectory!));
}

private async Task StartDownload() {
private async Task StartDownload(CancellationToken token = default) {
this.StateCurrent = 0;
this.StateMax = 1;

Expand All @@ -266,7 +266,7 @@ await this.Plugin.AddDownloadAsync(new DownloadTask {
Full = true,
Options = [],
Notification = null,
});
}, token);

this.StateCurrent += 1;
}
Expand Down
12 changes: 6 additions & 6 deletions Model/Api/GraphQl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,22 @@
namespace Heliosphere.Model.Api;

internal static class GraphQl {
internal static async Task<IReadOnlyList<IGetVersions_Package_Variants>> GetAllVersions(Guid packageId) {
var resp = await Plugin.GraphQl.GetVersions.ExecuteAsync(packageId);
internal static async Task<IReadOnlyList<IGetVersions_Package_Variants>> GetAllVersions(Guid packageId, CancellationToken token = default) {
var resp = await Plugin.GraphQl.GetVersions.ExecuteAsync(packageId, token);
resp.EnsureNoErrors();

var package = resp.Data?.Package ?? throw new MissingPackageException(packageId);
return package.Variants.Reverse().ToList();
}

internal static async Task<IGetNewestVersionInfo_Variant?> GetNewestVersion(Guid variantId) {
var resp = await Plugin.GraphQl.GetNewestVersionInfo.ExecuteAsync(variantId);
internal static async Task<IGetNewestVersionInfo_Variant?> GetNewestVersion(Guid variantId, CancellationToken token = default) {
var resp = await Plugin.GraphQl.GetNewestVersionInfo.ExecuteAsync(variantId, token);
resp.EnsureNoErrors();
return resp.Data?.Variant ?? throw new MissingVariantException(variantId);
}

internal static async Task<IReadOnlyList<IGetNewestVersionInfoMulti_Variants>> GetNewestVersions(IReadOnlyList<Guid> variantIds) {
var resp = await Plugin.GraphQl.GetNewestVersionInfoMulti.ExecuteAsync(variantIds);
internal static async Task<IReadOnlyList<IGetNewestVersionInfoMulti_Variants>> GetNewestVersions(IReadOnlyList<Guid> variantIds, CancellationToken token = default) {
var resp = await Plugin.GraphQl.GetNewestVersionInfoMulti.ExecuteAsync(variantIds, token);
resp.EnsureNoErrors();
return resp.Data?.Variants ?? Array.Empty<IGetNewestVersionInfoMulti_Variants>();
}
Expand Down
32 changes: 16 additions & 16 deletions Model/HeliosphereMeta.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,35 +44,35 @@ internal class HeliosphereMeta {

internal string ErrorName => $"{this.Name} v{this.Version} (P:{this.Id.ToCrockford()} Va:{this.VariantId.ToCrockford()} Ve:{this.VersionId.ToCrockford()})";

internal static async Task<HeliosphereMeta?> Load(string path) {
var text = await FileHelper.ReadAllTextAsync(path);
internal static async Task<HeliosphereMeta?> Load(string path, CancellationToken token = default) {
var text = await FileHelper.ReadAllTextAsync(path, token);
var obj = JsonConvert.DeserializeObject<JObject>(text);
if (obj == null) {
return null;
}

var (meta, changed) = await Convert(obj);
var (meta, changed) = await Convert(obj, token);
if (changed) {
var json = JsonConvert.SerializeObject(meta, Formatting.Indented);
await using var file = FileHelper.Create(path);
await file.WriteAsync(Encoding.UTF8.GetBytes(json));
await file.WriteAsync(Encoding.UTF8.GetBytes(json), token);
}

return meta;
}

private static async Task<(HeliosphereMeta, bool)> Convert(JObject config) {
var changed = await RunMigrations(config);
private static async Task<(HeliosphereMeta, bool)> Convert(JObject config, CancellationToken token = default) {
var changed = await RunMigrations(config, token);
return (config.ToObject<HeliosphereMeta>()!, changed);
}

private static async Task<bool> RunMigrations(JObject config) {
private static async Task<bool> RunMigrations(JObject config, CancellationToken token = default) {
var version = GetVersion();
var changed = false;
while (version < LatestVersion) {
switch (version) {
case 1:
await MigrateV1(config);
await MigrateV1(config, token);
break;
case 2:
MigrateV2(config);
Expand Down Expand Up @@ -107,7 +107,7 @@ uint GetVersion() {
}
}

private static async Task MigrateV1(JObject config) {
private static async Task MigrateV1(JObject config, CancellationToken token = default) {
var hasMetaVersion = config.Properties().Any(prop => prop.Name == nameof(MetaVersion));
var hasAuthorUuid = config.Properties().Any(prop => prop.Name == "AuthorUuid");

Expand All @@ -128,7 +128,7 @@ private static async Task MigrateV1(JObject config) {

// get new value for VersionId
var versionId = config[nameof(VersionId)]!.Value<int>();
var newVersionId = (await Plugin.GraphQl.ConvertVersionId.ExecuteAsync(versionId)).Data?.ConvertVersionId;
var newVersionId = (await Plugin.GraphQl.ConvertVersionId.ExecuteAsync(versionId, token)).Data?.ConvertVersionId;
if (newVersionId == null) {
throw new MetaMigrationException(1, 2, "Invalid version id while migrating Heliosphere meta");
}
Expand All @@ -137,7 +137,7 @@ private static async Task MigrateV1(JObject config) {

// get new value for VariantId
var variantId = config[nameof(VariantId)]!.Value<int>();
var newVariantId = (await Plugin.GraphQl.ConvertVariantId.ExecuteAsync(variantId)).Data?.ConvertVariantId;
var newVariantId = (await Plugin.GraphQl.ConvertVariantId.ExecuteAsync(variantId, token)).Data?.ConvertVariantId;
if (newVariantId == null) {
throw new MetaMigrationException(1, 2, "Invalid variant id while migrating Heliosphere meta");
}
Expand Down Expand Up @@ -201,7 +201,7 @@ internal static string ModDirectoryName(Guid id, string name, string version, Gu
/// </summary>
/// <param name="plugin">An instance of the plugin</param>
/// <returns>Task that completes when the download finishes</returns>
internal Task DownloadUpdates(Plugin plugin) {
internal Task DownloadUpdates(Plugin plugin, CancellationToken token = default) {
return Task.Run(async () => {
var name = new StringBuilder();
name.Append(this.Name);
Expand All @@ -219,7 +219,7 @@ internal Task DownloadUpdates(Plugin plugin) {
Minimized = false,
});
var info = await GraphQl.GetNewestVersion(this.VariantId);
var info = await GraphQl.GetNewestVersion(this.VariantId, token);
if (info == null) {
return;
}
Expand Down Expand Up @@ -251,7 +251,7 @@ await plugin.AddDownloadAsync(new DownloadTask {
Full = true,
Options = [],
Notification = null,
});
}, token);
}
} else {
plugin.DownloadCodes.TryGetCode(this.Id, out var key);
Expand All @@ -267,9 +267,9 @@ await InstallerWindow.OpenAndAdd(new InstallerWindow.OpenOptions {
DownloadKey = key,
PenumbraCollection = null,
Info = null,
});
}, token: token);
}
});
}, token);
}
}

Expand Down
Loading

0 comments on commit ebd9f52

Please sign in to comment.