sharp-chat/SharpChatCommon/StorageMigrator.cs

54 lines
2.4 KiB
C#

using Microsoft.Extensions.Logging;
using SharpChat.Messages;
using ZLogger;
namespace SharpChat;
public class StorageMigrator(ILogger logger, Storage source, Storage target) {
public async Task Migrate(CancellationToken cancellationToken) {
try {
logger.ZLogInformation($"Converting from {source.GetType().Name} to {target.GetType().Name}!");
logger.ZLogInformation($"Ensuring both source and target are fully upgraded...");
if(cancellationToken.IsCancellationRequested) return;
await source.UpgradeStorage();
if(cancellationToken.IsCancellationRequested) return;
await target.UpgradeStorage();
if(cancellationToken.IsCancellationRequested) return;
logger.ZLogInformation($"Creating message storage instances...");
MessageStorage sourceMsgs = source.CreateMessageStorage();
MessageStorage targetMsgs = target.CreateMessageStorage();
if(cancellationToken.IsCancellationRequested) return;
long msgCount = await sourceMsgs.CountMessages(includeDeleted: true);
if(msgCount < 1) {
logger.ZLogInformation($"No messages to migrate, skipping...");
} else {
logger.ZLogInformation($"Migrating {msgCount} message{(msgCount == 1 ? "" : "s")}...");
long migrated = 0;
DateTimeOffset lastReport = DateTimeOffset.UtcNow;
IEnumerable<Message> msgs = await sourceMsgs.GetMessages(take: null, includeDeleted: true);
foreach(Message msg in msgs) {
if(cancellationToken.IsCancellationRequested) break;
await targetMsgs.LogMessage(msg);
++migrated;
if(DateTimeOffset.UtcNow - lastReport > TimeSpan.FromMinutes(1)) {
lastReport = DateTimeOffset.UtcNow;
double completion = (double)migrated / msgCount;
logger.ZLogInformation($"{migrated} of {msgCount} message{(migrated == 1 ? "" : "s")} migrated ({completion:P2})...");
}
}
logger.ZLogInformation($"Migrated {migrated} message{(migrated == 1 ? "" : "s")}!");
}
} catch(Exception ex) {
logger.ZLogError($"Error during migration: {ex}");
throw;
}
}
}