using LightlessSync.Interop.Ipc; using LightlessSync.LightlessConfiguration; using LightlessSync.Services.Mediator; using Microsoft.Extensions.Logging; namespace LightlessSync.Services; public sealed class PenumbraTempCollectionJanitor : DisposableMediatorSubscriberBase { private readonly IpcManager _ipc; private readonly PenumbraJanitorConfigService _config; private int _ran; public PenumbraTempCollectionJanitor( ILogger logger, LightlessMediator mediator, IpcManager ipc, PenumbraJanitorConfigService config) : base(logger, mediator) { _ipc = ipc; _config = config; Mediator.Subscribe(this, _ => CleanupOrphansOnBoot()); } public void Register(Guid id) { if (id == Guid.Empty) return; if (_config.Current.OrphanableTempCollections.Add(id)) _config.Save(); } public void Unregister(Guid id) { if (id == Guid.Empty) return; if (_config.Current.OrphanableTempCollections.Remove(id)) _config.Save(); } private void CleanupOrphansOnBoot() { if (Interlocked.Exchange(ref _ran, 1) == 1) return; if (!_ipc.Penumbra.APIAvailable) return; var ids = _config.Current.OrphanableTempCollections.ToArray(); if (ids.Length == 0) return; var appId = Guid.NewGuid(); Logger.LogInformation("Cleaning up {count} orphaned Lightless temp collections found in configuration", ids.Length); foreach (var id in ids) { try { _ipc.Penumbra.RemoveTemporaryCollectionAsync(Logger, appId, id) .GetAwaiter().GetResult(); } catch (Exception ex) { Logger.LogDebug(ex, "Failed removing orphaned temp collection {id}", id); } } _config.Current.OrphanableTempCollections.Clear(); _config.Save(); // Notify cleanup complete Mediator.Publish(new PenumbraTempCollectionsCleanedMessage()); } }