removal of *temporary* collections
This commit is contained in:
@@ -1,4 +1,6 @@
|
||||
using LightlessSync.Interop.Ipc;
|
||||
using System.Linq;
|
||||
using LightlessSync.Interop.Ipc;
|
||||
using LightlessSync.LightlessConfiguration.Models;
|
||||
using LightlessSync.LightlessConfiguration;
|
||||
using LightlessSync.Services.Mediator;
|
||||
using Microsoft.Extensions.Logging;
|
||||
@@ -10,6 +12,7 @@ public sealed class PenumbraTempCollectionJanitor : DisposableMediatorSubscriber
|
||||
private readonly IpcManager _ipc;
|
||||
private readonly LightlessConfigService _config;
|
||||
private int _ran;
|
||||
private static readonly TimeSpan OrphanCleanupDelay = TimeSpan.FromDays(1);
|
||||
|
||||
public PenumbraTempCollectionJanitor(
|
||||
ILogger<PenumbraTempCollectionJanitor> logger,
|
||||
@@ -26,15 +29,46 @@ public sealed class PenumbraTempCollectionJanitor : DisposableMediatorSubscriber
|
||||
public void Register(Guid id)
|
||||
{
|
||||
if (id == Guid.Empty) return;
|
||||
if (_config.Current.OrphanableTempCollections.Add(id))
|
||||
var changed = false;
|
||||
var config = _config.Current;
|
||||
if (config.OrphanableTempCollections.Add(id))
|
||||
{
|
||||
changed = true;
|
||||
}
|
||||
|
||||
var now = DateTime.UtcNow;
|
||||
var existing = config.OrphanableTempCollectionEntries.FirstOrDefault(entry => entry.Id == id);
|
||||
if (existing is null)
|
||||
{
|
||||
config.OrphanableTempCollectionEntries.Add(new OrphanableTempCollectionEntry
|
||||
{
|
||||
Id = id,
|
||||
RegisteredAtUtc = now
|
||||
});
|
||||
changed = true;
|
||||
}
|
||||
else if (existing.RegisteredAtUtc == DateTime.MinValue)
|
||||
{
|
||||
existing.RegisteredAtUtc = now;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (changed)
|
||||
{
|
||||
_config.Save();
|
||||
}
|
||||
}
|
||||
|
||||
public void Unregister(Guid id)
|
||||
{
|
||||
if (id == Guid.Empty) return;
|
||||
if (_config.Current.OrphanableTempCollections.Remove(id))
|
||||
var config = _config.Current;
|
||||
var changed = config.OrphanableTempCollections.Remove(id);
|
||||
changed |= RemoveEntry(config.OrphanableTempCollectionEntries, id) > 0;
|
||||
if (changed)
|
||||
{
|
||||
_config.Save();
|
||||
}
|
||||
}
|
||||
|
||||
private void CleanupOrphansOnBoot()
|
||||
@@ -45,14 +79,33 @@ public sealed class PenumbraTempCollectionJanitor : DisposableMediatorSubscriber
|
||||
if (!_ipc.Penumbra.APIAvailable)
|
||||
return;
|
||||
|
||||
var ids = _config.Current.OrphanableTempCollections.ToArray();
|
||||
if (ids.Length == 0)
|
||||
var config = _config.Current;
|
||||
var ids = config.OrphanableTempCollections;
|
||||
var entries = config.OrphanableTempCollectionEntries;
|
||||
if (ids.Count == 0 && entries.Count == 0)
|
||||
return;
|
||||
|
||||
var appId = Guid.NewGuid();
|
||||
Logger.LogInformation("Cleaning up {count} orphaned Lightless temp collections found in configuration", ids.Length);
|
||||
var now = DateTime.UtcNow;
|
||||
var changed = EnsureEntries(ids, entries, now);
|
||||
var cutoff = now - OrphanCleanupDelay;
|
||||
var expired = entries
|
||||
.Where(entry => entry.Id != Guid.Empty && entry.RegisteredAtUtc != DateTime.MinValue && entry.RegisteredAtUtc <= cutoff)
|
||||
.Select(entry => entry.Id)
|
||||
.Distinct()
|
||||
.ToList();
|
||||
if (expired.Count == 0)
|
||||
{
|
||||
if (changed)
|
||||
{
|
||||
_config.Save();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var id in ids)
|
||||
var appId = Guid.NewGuid();
|
||||
Logger.LogInformation("Cleaning up {count} orphaned Lightless temp collections older than {delay}", expired.Count, OrphanCleanupDelay);
|
||||
|
||||
foreach (var id in expired)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -65,7 +118,70 @@ public sealed class PenumbraTempCollectionJanitor : DisposableMediatorSubscriber
|
||||
}
|
||||
}
|
||||
|
||||
_config.Current.OrphanableTempCollections.Clear();
|
||||
foreach (var id in expired)
|
||||
{
|
||||
ids.Remove(id);
|
||||
}
|
||||
|
||||
foreach (var id in expired)
|
||||
{
|
||||
RemoveEntry(entries, id);
|
||||
}
|
||||
|
||||
_config.Save();
|
||||
}
|
||||
}
|
||||
|
||||
private static int RemoveEntry(List<OrphanableTempCollectionEntry> entries, Guid id)
|
||||
{
|
||||
var removed = 0;
|
||||
for (var i = entries.Count - 1; i >= 0; i--)
|
||||
{
|
||||
if (entries[i].Id != id)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
entries.RemoveAt(i);
|
||||
removed++;
|
||||
}
|
||||
|
||||
return removed;
|
||||
}
|
||||
|
||||
private static bool EnsureEntries(HashSet<Guid> ids, List<OrphanableTempCollectionEntry> entries, DateTime now)
|
||||
{
|
||||
var changed = false;
|
||||
foreach (var id in ids)
|
||||
{
|
||||
if (id == Guid.Empty)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (entries.Any(entry => entry.Id == id))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
entries.Add(new OrphanableTempCollectionEntry
|
||||
{
|
||||
Id = id,
|
||||
RegisteredAtUtc = now
|
||||
});
|
||||
changed = true;
|
||||
}
|
||||
|
||||
foreach (var entry in entries)
|
||||
{
|
||||
if (entry.Id == Guid.Empty || entry.RegisteredAtUtc != DateTime.MinValue)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
entry.RegisteredAtUtc = now;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user