removal of *temporary* collections
This commit is contained in:
@@ -1,10 +1,8 @@
|
||||
using System.Collections.Concurrent;
|
||||
using Dalamud.Plugin;
|
||||
using LightlessSync.Interop.Ipc.Framework;
|
||||
using LightlessSync.Services;
|
||||
using LightlessSync.Services.Mediator;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Penumbra.Api.Enums;
|
||||
using Penumbra.Api.IpcSubscribers;
|
||||
|
||||
namespace LightlessSync.Interop.Ipc.Penumbra;
|
||||
@@ -16,10 +14,6 @@ public sealed class PenumbraCollections : PenumbraBase
|
||||
private readonly DeleteTemporaryCollection _removeTemporaryCollection;
|
||||
private readonly AddTemporaryMod _addTemporaryMod;
|
||||
private readonly RemoveTemporaryMod _removeTemporaryMod;
|
||||
private readonly GetCollections _getCollections;
|
||||
private readonly ConcurrentDictionary<Guid, string> _activeTemporaryCollections = new();
|
||||
|
||||
private int _cleanupScheduled;
|
||||
|
||||
public PenumbraCollections(
|
||||
ILogger logger,
|
||||
@@ -32,7 +26,6 @@ public sealed class PenumbraCollections : PenumbraBase
|
||||
_removeTemporaryCollection = new DeleteTemporaryCollection(pluginInterface);
|
||||
_addTemporaryMod = new AddTemporaryMod(pluginInterface);
|
||||
_removeTemporaryMod = new RemoveTemporaryMod(pluginInterface);
|
||||
_getCollections = new GetCollections(pluginInterface);
|
||||
}
|
||||
|
||||
public override string Name => "Penumbra.Collections";
|
||||
@@ -62,16 +55,11 @@ public sealed class PenumbraCollections : PenumbraBase
|
||||
var (collectionId, collectionName) = await DalamudUtil.RunOnFrameworkThread(() =>
|
||||
{
|
||||
var name = $"Lightless_{uid}";
|
||||
_createNamedTemporaryCollection.Invoke(name, name, out var tempCollectionId);
|
||||
logger.LogTrace("Creating Temp Collection {CollectionName}, GUID: {CollectionId}", name, tempCollectionId);
|
||||
var createResult = _createNamedTemporaryCollection.Invoke(name, name, out var tempCollectionId);
|
||||
logger.LogTrace("Creating Temp Collection {CollectionName}, GUID: {CollectionId}, Result: {Result}", name, tempCollectionId, createResult);
|
||||
return (tempCollectionId, name);
|
||||
}).ConfigureAwait(false);
|
||||
|
||||
if (collectionId != Guid.Empty)
|
||||
{
|
||||
_activeTemporaryCollections[collectionId] = collectionName;
|
||||
}
|
||||
|
||||
return collectionId;
|
||||
}
|
||||
|
||||
@@ -89,7 +77,6 @@ public sealed class PenumbraCollections : PenumbraBase
|
||||
logger.LogTrace("[{ApplicationId}] RemoveTemporaryCollection: {Result}", applicationId, result);
|
||||
}).ConfigureAwait(false);
|
||||
|
||||
_activeTemporaryCollections.TryRemove(collectionId, out _);
|
||||
}
|
||||
|
||||
public async Task SetTemporaryModsAsync(ILogger logger, Guid applicationId, Guid collectionId, Dictionary<string, string> modPaths)
|
||||
@@ -131,67 +118,5 @@ public sealed class PenumbraCollections : PenumbraBase
|
||||
|
||||
protected override void HandleStateChange(IpcConnectionState previous, IpcConnectionState current)
|
||||
{
|
||||
if (current == IpcConnectionState.Available)
|
||||
{
|
||||
ScheduleCleanup();
|
||||
}
|
||||
else if (previous == IpcConnectionState.Available && current != IpcConnectionState.Available)
|
||||
{
|
||||
Interlocked.Exchange(ref _cleanupScheduled, 0);
|
||||
}
|
||||
}
|
||||
|
||||
private void ScheduleCleanup()
|
||||
{
|
||||
if (Interlocked.Exchange(ref _cleanupScheduled, 1) != 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_ = Task.Run(CleanupTemporaryCollectionsAsync);
|
||||
}
|
||||
|
||||
private async Task CleanupTemporaryCollectionsAsync()
|
||||
{
|
||||
if (!IsAvailable)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var collections = await DalamudUtil.RunOnFrameworkThread(() => _getCollections.Invoke()).ConfigureAwait(false);
|
||||
foreach (var (collectionId, name) in collections)
|
||||
{
|
||||
if (!IsLightlessCollectionName(name) || _activeTemporaryCollections.ContainsKey(collectionId))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
Logger.LogDebug("Cleaning up stale temporary collection {CollectionName} ({CollectionId})", name, collectionId);
|
||||
var deleteResult = await DalamudUtil.RunOnFrameworkThread(() =>
|
||||
{
|
||||
var result = (PenumbraApiEc)_removeTemporaryCollection.Invoke(collectionId);
|
||||
Logger.LogTrace("Cleanup RemoveTemporaryCollection result for {CollectionName} ({CollectionId}): {Result}", name, collectionId, result);
|
||||
return result;
|
||||
}).ConfigureAwait(false);
|
||||
|
||||
if (deleteResult == PenumbraApiEc.Success)
|
||||
{
|
||||
_activeTemporaryCollections.TryRemove(collectionId, out _);
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.LogDebug("Skipped removing temporary collection {CollectionName} ({CollectionId}). Result: {Result}", name, collectionId, deleteResult);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.LogWarning(ex, "Failed to clean up Penumbra temporary collections");
|
||||
}
|
||||
}
|
||||
|
||||
private static bool IsLightlessCollectionName(string? name)
|
||||
=> !string.IsNullOrEmpty(name) && name.StartsWith("Lightless_", StringComparison.Ordinal);
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ using LightlessSync.PlayerData.Handlers;
|
||||
using LightlessSync.Services;
|
||||
using LightlessSync.Services.Mediator;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using Penumbra.Api.Helpers;
|
||||
using Penumbra.Api.IpcSubscribers;
|
||||
@@ -42,17 +43,33 @@ public sealed class PenumbraResource : PenumbraBase
|
||||
return null;
|
||||
}
|
||||
|
||||
return await DalamudUtil.RunOnFrameworkThread(() =>
|
||||
var requestId = Guid.NewGuid();
|
||||
var totalTimer = Stopwatch.StartNew();
|
||||
logger.LogTrace("[{requestId}] Requesting Penumbra.GetGameObjectResourcePaths for {handler}", requestId, handler);
|
||||
|
||||
var result = await DalamudUtil.RunOnFrameworkThread(() =>
|
||||
{
|
||||
logger.LogTrace("Calling On IPC: Penumbra.GetGameObjectResourcePaths");
|
||||
var idx = handler.GetGameObject()?.ObjectIndex;
|
||||
if (idx == null)
|
||||
{
|
||||
logger.LogTrace("[{requestId}] GetGameObjectResourcePaths aborted (missing object index) for {handler}", requestId, handler);
|
||||
return null;
|
||||
}
|
||||
|
||||
return _gameObjectResourcePaths.Invoke(idx.Value)[0];
|
||||
logger.LogTrace("[{requestId}] Invoking Penumbra.GetGameObjectResourcePaths for index {index}", requestId, idx.Value);
|
||||
var invokeTimer = Stopwatch.StartNew();
|
||||
var data = _gameObjectResourcePaths.Invoke(idx.Value)[0];
|
||||
invokeTimer.Stop();
|
||||
logger.LogTrace("[{requestId}] Penumbra.GetGameObjectResourcePaths returned {count} entries in {elapsedMs}ms",
|
||||
requestId, data?.Count ?? 0, invokeTimer.ElapsedMilliseconds);
|
||||
return data;
|
||||
}).ConfigureAwait(false);
|
||||
|
||||
totalTimer.Stop();
|
||||
logger.LogTrace("[{requestId}] Penumbra.GetGameObjectResourcePaths finished in {elapsedMs}ms (null: {isNull})",
|
||||
requestId, totalTimer.ElapsedMilliseconds, result is null);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public string GetMetaManipulations()
|
||||
|
||||
Reference in New Issue
Block a user