mirror of
https://github.com/goatcorp/Dalamud.git
synced 2025-12-12 18:27:23 +01:00
Unindent LoadAllPlugins by converting it to an async function, fixing task wait problems meanwhile (#966)
This commit is contained in:
parent
039dc1b447
commit
c46cb36549
3 changed files with 70 additions and 106 deletions
|
|
@ -376,6 +376,7 @@ namespace Dalamud.Game
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
File.WriteAllText(this.cacheFile.FullName, JsonConvert.SerializeObject(this.textCache));
|
File.WriteAllText(this.cacheFile.FullName, JsonConvert.SerializeObject(this.textCache));
|
||||||
|
Log.Information("Saved cache to {CachePath}", this.cacheFile);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -334,7 +334,8 @@ internal partial class PluginManager : IDisposable, IServiceType
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// This should only be called during Dalamud startup.
|
/// This should only be called during Dalamud startup.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
public void LoadAllPlugins()
|
/// <returns>The task.</returns>
|
||||||
|
public async Task LoadAllPlugins()
|
||||||
{
|
{
|
||||||
var pluginDefs = new List<PluginDef>();
|
var pluginDefs = new List<PluginDef>();
|
||||||
var devPluginDefs = new List<PluginDef>();
|
var devPluginDefs = new List<PluginDef>();
|
||||||
|
|
@ -405,8 +406,9 @@ internal partial class PluginManager : IDisposable, IServiceType
|
||||||
// Dev plugins should load first.
|
// Dev plugins should load first.
|
||||||
pluginDefs.InsertRange(0, devPluginDefs);
|
pluginDefs.InsertRange(0, devPluginDefs);
|
||||||
|
|
||||||
async Task LoadPluginOnBoot(string logPrefix, PluginDef pluginDef)
|
async Task LoadPluginOnBoot(string logPrefix, PluginDef pluginDef, CancellationToken token)
|
||||||
{
|
{
|
||||||
|
token.ThrowIfCancellationRequested();
|
||||||
using (Timings.Start($"{pluginDef.DllFile.Name}: {logPrefix}Boot"))
|
using (Timings.Start($"{pluginDef.DllFile.Name}: {logPrefix}Boot"))
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
|
@ -429,24 +431,30 @@ internal partial class PluginManager : IDisposable, IServiceType
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async Task LoadPluginsSync(string logPrefix, IEnumerable<PluginDef> pluginDefsList)
|
async Task LoadPluginsSync(string logPrefix, IEnumerable<PluginDef> pluginDefsList, CancellationToken token)
|
||||||
{
|
{
|
||||||
Log.Information("============= LoadPluginsSync START =============");
|
Log.Information($"============= LoadPluginsSync({logPrefix}) START =============");
|
||||||
|
|
||||||
foreach (var pluginDef in pluginDefsList)
|
foreach (var pluginDef in pluginDefsList)
|
||||||
await LoadPluginOnBoot(logPrefix, pluginDef);
|
await LoadPluginOnBoot(logPrefix, pluginDef, token).ConfigureAwait(false);
|
||||||
|
|
||||||
Log.Information("============= LoadPluginsSync END =============");
|
Log.Information($"============= LoadPluginsSync({logPrefix}) END =============");
|
||||||
}
|
}
|
||||||
|
|
||||||
Task LoadPluginsAsync(string logPrefix, IEnumerable<PluginDef> pluginDefsList)
|
async Task LoadPluginsAsync(string logPrefix, IEnumerable<PluginDef> pluginDefsList, CancellationToken token)
|
||||||
{
|
{
|
||||||
Log.Information("============= LoadPluginsAsync START =============");
|
Log.Information($"============= LoadPluginsAsync({logPrefix}) START =============");
|
||||||
return Task.WhenAll(
|
|
||||||
|
await Task.WhenAll(
|
||||||
pluginDefsList
|
pluginDefsList
|
||||||
.Select(pluginDef => Task.Run(Timings.AttachTimingHandle(
|
.Select(pluginDef =>
|
||||||
() => LoadPluginOnBoot(logPrefix, pluginDef))))
|
Task.Run(
|
||||||
.ToArray()).ContinueWith(t => Log.Information($"============= LoadPluginsAsync END {t.IsCompletedSuccessfully} ============="));
|
Timings.AttachTimingHandle(
|
||||||
|
() => LoadPluginOnBoot(logPrefix, pluginDef, token)),
|
||||||
|
token))
|
||||||
|
.ToArray()).ConfigureAwait(false);
|
||||||
|
|
||||||
|
Log.Information($"============= LoadPluginsAsync({logPrefix}) END =============");
|
||||||
}
|
}
|
||||||
|
|
||||||
var syncPlugins = pluginDefs.Where(def => def.Manifest?.LoadSync == true).ToList();
|
var syncPlugins = pluginDefs.Where(def => def.Manifest?.LoadSync == true).ToList();
|
||||||
|
|
@ -456,107 +464,62 @@ internal partial class PluginManager : IDisposable, IServiceType
|
||||||
var tokenSource = new CancellationTokenSource(TimeSpan.FromMinutes(5));
|
var tokenSource = new CancellationTokenSource(TimeSpan.FromMinutes(5));
|
||||||
|
|
||||||
// Load plugins that can be loaded anytime
|
// Load plugins that can be loaded anytime
|
||||||
LoadPluginsSync(
|
await LoadPluginsSync(
|
||||||
"AnytimeSync",
|
"AnytimeSync",
|
||||||
syncPlugins.Where(def => def.Manifest?.LoadRequiredState == 2)).GetAwaiter().GetResult();
|
syncPlugins.Where(def => def.Manifest?.LoadRequiredState == 2),
|
||||||
loadTasks.Add(
|
tokenSource.Token);
|
||||||
Task.Run(
|
loadTasks.Add(LoadPluginsAsync(
|
||||||
() => LoadPluginsAsync(
|
"AnytimeAsync",
|
||||||
"AnytimeAsync",
|
asyncPlugins.Where(def => def.Manifest?.LoadRequiredState == 2),
|
||||||
asyncPlugins.Where(def => def.Manifest?.LoadRequiredState == 2)),
|
tokenSource.Token));
|
||||||
tokenSource.Token));
|
|
||||||
|
|
||||||
// Load plugins that want to be loaded during Framework.Tick
|
// Pass the rest of plugin loading to another thread(task)
|
||||||
loadTasks.Add(
|
_ = Task.Run(
|
||||||
Task.Run(
|
async () =>
|
||||||
() => Service<Framework>
|
{
|
||||||
.GetAsync()
|
// Load plugins that want to be loaded during Framework.Tick
|
||||||
.ContinueWith(
|
var framework = await Service<Framework>.GetAsync().ConfigureAwait(false);
|
||||||
x => x.Result.RunOnTick(
|
await framework.RunOnTick(
|
||||||
() => LoadPluginsSync(
|
() => LoadPluginsSync(
|
||||||
"FrameworkTickSync",
|
"FrameworkTickSync",
|
||||||
syncPlugins.Where(def => def.Manifest?.LoadRequiredState == 1)),
|
syncPlugins.Where(def => def.Manifest?.LoadRequiredState == 1),
|
||||||
cancellationToken: tokenSource.Token),
|
tokenSource.Token),
|
||||||
tokenSource.Token,
|
cancellationToken: tokenSource.Token).ConfigureAwait(false);
|
||||||
TaskContinuationOptions.RunContinuationsAsynchronously,
|
loadTasks.Add(LoadPluginsAsync(
|
||||||
TaskScheduler.Default)
|
"FrameworkTickAsync",
|
||||||
.Unwrap()
|
asyncPlugins.Where(def => def.Manifest?.LoadRequiredState == 1),
|
||||||
.ContinueWith(
|
tokenSource.Token));
|
||||||
_ => LoadPluginsAsync(
|
|
||||||
"FrameworkTickAsync",
|
|
||||||
asyncPlugins.Where(def => def.Manifest?.LoadRequiredState == 1)),
|
|
||||||
tokenSource.Token,
|
|
||||||
TaskContinuationOptions.RunContinuationsAsynchronously,
|
|
||||||
TaskScheduler.Default)
|
|
||||||
.Unwrap(),
|
|
||||||
tokenSource.Token));
|
|
||||||
|
|
||||||
// Load plugins that want to be loaded during Framework.Tick, when drawing facilities are available
|
// Load plugins that want to be loaded during Framework.Tick, when drawing facilities are available
|
||||||
loadTasks.Add(
|
_ = await Service<InterfaceManager.InterfaceManagerWithScene>.GetAsync().ConfigureAwait(false);
|
||||||
Task.Run(
|
await framework.RunOnTick(
|
||||||
() => Service<InterfaceManager.InterfaceManagerWithScene>
|
() => LoadPluginsSync(
|
||||||
.GetAsync()
|
"DrawAvailableSync",
|
||||||
.ContinueWith(
|
syncPlugins.Where(def => def.Manifest?.LoadRequiredState is 0 or null),
|
||||||
_ => Service<Framework>.Get().RunOnTick(
|
tokenSource.Token),
|
||||||
() => LoadPluginsSync(
|
cancellationToken: tokenSource.Token);
|
||||||
"DrawAvailableSync",
|
loadTasks.Add(LoadPluginsAsync(
|
||||||
syncPlugins.Where(def => def.Manifest?.LoadRequiredState is 0 or null)),
|
|
||||||
cancellationToken: tokenSource.Token),
|
|
||||||
tokenSource.Token)
|
|
||||||
.Unwrap()
|
|
||||||
.ContinueWith(
|
|
||||||
_ => LoadPluginsAsync(
|
|
||||||
"DrawAvailableAsync",
|
"DrawAvailableAsync",
|
||||||
asyncPlugins.Where(def => def.Manifest?.LoadRequiredState is 0 or null)),
|
asyncPlugins.Where(def => def.Manifest?.LoadRequiredState is 0 or null),
|
||||||
tokenSource.Token)
|
tokenSource.Token));
|
||||||
.Unwrap(),
|
|
||||||
tokenSource.Token));
|
|
||||||
|
|
||||||
// Save signatures when all plugins are done loading, successful or not.
|
// Save signatures when all plugins are done loading, successful or not.
|
||||||
_ = Task
|
try
|
||||||
.WhenAll(loadTasks)
|
|
||||||
.ContinueWith(
|
|
||||||
t =>
|
|
||||||
{
|
{
|
||||||
Log.Information("Task.WhenAll continuing");
|
await Task.WhenAll(loadTasks).ConfigureAwait(false);
|
||||||
if (!t.IsCompletedSuccessfully)
|
Log.Information("Loaded plugins on boot");
|
||||||
{
|
}
|
||||||
foreach (var loadTask in loadTasks)
|
catch (Exception e)
|
||||||
{
|
|
||||||
if (!loadTask.IsCompletedSuccessfully)
|
|
||||||
{
|
|
||||||
if (loadTask.Exception != null)
|
|
||||||
{
|
|
||||||
Log.Error(loadTask.Exception, " => Exception during load");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Log.Error($" => Task failed, canceled: {t.IsCanceled} faulted: {t.IsFaulted}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Service<SigScanner>.GetAsync();
|
|
||||||
},
|
|
||||||
tokenSource.Token,
|
|
||||||
TaskContinuationOptions.RunContinuationsAsynchronously,
|
|
||||||
TaskScheduler.Default)
|
|
||||||
.Unwrap()
|
|
||||||
.ContinueWith(
|
|
||||||
sigScannerTask =>
|
|
||||||
{
|
{
|
||||||
Log.Information("sigScannerTask continuing");
|
Log.Error(e, "Failed to load at least one plugin");
|
||||||
|
}
|
||||||
|
|
||||||
this.PluginsReady = true;
|
var sigScanner = await Service<SigScanner>.GetAsync().ConfigureAwait(false);
|
||||||
this.NotifyInstalledPluginsChanged();
|
this.PluginsReady = true;
|
||||||
|
this.NotifyInstalledPluginsChanged();
|
||||||
sigScannerTask.Result.Save();
|
sigScanner.Save();
|
||||||
},
|
},
|
||||||
tokenSource.Token,
|
tokenSource.Token);
|
||||||
TaskContinuationOptions.RunContinuationsAsynchronously,
|
|
||||||
TaskScheduler.Default)
|
|
||||||
.ConfigureAwait(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ public class StartupPluginLoader : IServiceType
|
||||||
|
|
||||||
using (Timings.Start("PM Load Sync Plugins"))
|
using (Timings.Start("PM Load Sync Plugins"))
|
||||||
{
|
{
|
||||||
pluginManager.LoadAllPlugins();
|
pluginManager.LoadAllPlugins().Wait();
|
||||||
Log.Information("[T3] PML OK!");
|
Log.Information("[T3] PML OK!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue