Files
AI-Studio/app/MindWork AI Studio/Tools/Services/TemporaryChatService.cs
T

109 lines
4.7 KiB
C#
Raw Normal View History

2024-07-13 10:37:57 +02:00
using AIStudio.Settings;
using AIStudio.Settings.DataModel;
2024-07-13 10:37:57 +02:00
2024-08-21 08:30:01 +02:00
namespace AIStudio.Tools.Services;
2024-07-13 10:37:57 +02:00
public sealed class TemporaryChatService(ILogger<TemporaryChatService> logger, SettingsManager settingsManager) : BackgroundService
2024-07-13 10:37:57 +02:00
{
private static readonly TimeSpan CHECK_INTERVAL = TimeSpan.FromDays(1);
private static bool IS_INITIALIZED;
#region Overrides of BackgroundService
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested && !IS_INITIALIZED)
await Task.Delay(TimeSpan.FromSeconds(3), stoppingToken);
logger.LogInformation("The temporary chat maintenance service was initialized.");
2024-09-01 20:10:03 +02:00
2024-08-05 21:12:52 +02:00
if(settingsManager.ConfigurationData.Workspace.StorageTemporaryMaintenancePolicy is WorkspaceStorageTemporaryMaintenancePolicy.NO_AUTOMATIC_MAINTENANCE)
2024-07-13 10:37:57 +02:00
{
logger.LogWarning("Automatic maintenance of temporary chat storage is disabled. Exiting maintenance service.");
2024-07-13 10:37:57 +02:00
return;
}
await this.StartMaintenanceAsync();
2024-07-13 10:37:57 +02:00
while (!stoppingToken.IsCancellationRequested)
{
await Task.Delay(CHECK_INTERVAL, stoppingToken);
await this.StartMaintenanceAsync();
2024-07-13 10:37:57 +02:00
}
}
#endregion
internal async Task StartMaintenanceAsync()
2024-07-13 10:37:57 +02:00
{
logger.LogInformation("Starting maintenance of temporary chat storage.");
2024-07-13 10:37:57 +02:00
var temporaryDirectories = Path.Join(SettingsManager.DataDirectory, "tempChats");
if(!Directory.Exists(temporaryDirectories))
2024-09-01 20:10:03 +02:00
{
logger.LogWarning("Temporary chat storage directory does not exist. End maintenance.");
return;
2024-09-01 20:10:03 +02:00
}
2024-07-13 10:37:57 +02:00
foreach (var tempChatDirPath in Directory.EnumerateDirectories(temporaryDirectories))
{
var chatPath = Path.Join(tempChatDirPath, "thread.json");
var chatMetadata = new FileInfo(chatPath);
if (!chatMetadata.Exists)
continue;
var lastWriteTime = chatMetadata.LastWriteTimeUtc;
2024-08-05 21:12:52 +02:00
var deleteChat = settingsManager.ConfigurationData.Workspace.StorageTemporaryMaintenancePolicy switch
2024-07-13 10:37:57 +02:00
{
WorkspaceStorageTemporaryMaintenancePolicy.DELETE_OLDER_THAN_7_DAYS => DateTime.UtcNow - lastWriteTime > TimeSpan.FromDays(7),
WorkspaceStorageTemporaryMaintenancePolicy.DELETE_OLDER_THAN_30_DAYS => DateTime.UtcNow - lastWriteTime > TimeSpan.FromDays(30),
WorkspaceStorageTemporaryMaintenancePolicy.DELETE_OLDER_THAN_90_DAYS => DateTime.UtcNow - lastWriteTime > TimeSpan.FromDays(90),
WorkspaceStorageTemporaryMaintenancePolicy.DELETE_OLDER_THAN_180_DAYS => DateTime.UtcNow - lastWriteTime > TimeSpan.FromDays(180),
WorkspaceStorageTemporaryMaintenancePolicy.DELETE_OLDER_THAN_365_DAYS => DateTime.UtcNow - lastWriteTime > TimeSpan.FromDays(365),
_ => false,
};
if(deleteChat)
2024-09-01 20:10:03 +02:00
{
logger.LogInformation($"Deleting temporary chat storage directory '{tempChatDirPath}' due to maintenance policy.");
await this.DeleteTemporaryChatAsync(tempChatDirPath);
2024-09-01 20:10:03 +02:00
}
2024-07-13 10:37:57 +02:00
}
logger.LogInformation("Finished maintenance of temporary chat storage.");
2024-07-13 10:37:57 +02:00
}
/// <summary>
/// Deletes one temporary chat the way the user deletes a chat, so that what it received goes along.
/// </summary>
/// <remarks>
/// A chat which cannot go now, e.g., since another operation holds it or a file of it is open,
/// stays until the next maintenance. Its failure must not end this service, nor the app with it.
/// </remarks>
/// <param name="tempChatDirPath">The directory of the chat.</param>
private async Task DeleteTemporaryChatAsync(string tempChatDirPath)
{
try
{
if (Guid.TryParse(Path.GetFileName(tempChatDirPath), out var chatId))
{
if (!await WorkspaceBehaviour.DeleteChatWithoutAskingAsync(Guid.Empty, chatId))
logger.LogWarning("The temporary chat '{ChatId}' is busy, so the next maintenance deletes it.", chatId);
return;
}
// Not a chat AI Studio made, so nothing else knows about it:
Directory.Delete(tempChatDirPath, true);
WorkspaceBehaviour.InvalidateWorkspaceTreeCache();
}
catch (Exception exception)
{
logger.LogWarning(exception, "Could not delete the temporary chat storage directory '{Directory}'. The next maintenance tries again.", tempChatDirPath);
}
}
2024-07-13 10:37:57 +02:00
public static void Initialize()
{
IS_INITIALIZED = true;
}
}