[backend/core] Improve user deletes (ISH-222)

This commit is contained in:
Laura Hausmann 2024-04-10 20:53:50 +02:00
parent 3ef83a1cd3
commit 806bfca099
No known key found for this signature in database
GPG key ID: D044E84C5BE01605
2 changed files with 57 additions and 20 deletions

View file

@ -39,6 +39,9 @@ public class BackgroundTaskQueue()
case FilterExpiryJobData filterExpiryJob: case FilterExpiryJobData filterExpiryJob:
await ProcessFilterExpiry(filterExpiryJob, scope, token); await ProcessFilterExpiry(filterExpiryJob, scope, token);
break; break;
case UserDeleteJobData userDeleteJob:
await ProcessUserDelete(userDeleteJob, scope, token);
break;
} }
} }
@ -213,12 +216,59 @@ public class BackgroundTaskQueue()
db.Remove(filter); db.Remove(filter);
await db.SaveChangesAsync(token); await db.SaveChangesAsync(token);
} }
private static async Task ProcessUserDelete(
UserDeleteJobData jobData,
IServiceProvider scope,
CancellationToken token
)
{
var db = scope.GetRequiredService<DatabaseContext>();
var queue = scope.GetRequiredService<QueueService>();
var logger = scope.GetRequiredService<ILogger<BackgroundTaskQueue>>();
var followupTaskSvc = scope.GetRequiredService<FollowupTaskService>();
logger.LogDebug("Processing delete for user {id}", jobData.UserId);
var user = await db.Users.FirstOrDefaultAsync(p => p.Id == jobData.UserId, token);
if (user == null)
{
logger.LogDebug("Failed to delete user {id}: id not found in database", jobData.UserId);
return;
}
var fileIds = await db.DriveFiles.Where(p => p.User == user).Select(p => p.Id).ToListAsync(token);
logger.LogDebug("Removing {count} files for user {id}", fileIds.Count, user.Id);
foreach (var id in fileIds)
{
await queue.BackgroundTaskQueue.EnqueueAsync(new DriveFileDeleteJobData
{
DriveFileId = id, Expire = false
});
}
db.Remove(user);
await db.SaveChangesAsync(token);
await followupTaskSvc.ExecuteTask("UpdateInstanceUserCounter", async provider =>
{
var bgDb = provider.GetRequiredService<DatabaseContext>();
var bgInstanceSvc = provider.GetRequiredService<InstanceService>();
var dbInstance = await bgInstanceSvc.GetUpdatedInstanceMetadataAsync(user);
await bgDb.Instances.Where(p => p.Id == dbInstance.Id)
.ExecuteUpdateAsync(p => p.SetProperty(i => i.UsersCount, i => i.UsersCount - 1),
cancellationToken: token);
});
logger.LogDebug("User {id} deleted successfully", jobData.UserId);
}
} }
[JsonDerivedType(typeof(DriveFileDeleteJobData), "driveFileDelete")] [JsonDerivedType(typeof(DriveFileDeleteJobData), "driveFileDelete")]
[JsonDerivedType(typeof(PollExpiryJobData), "pollExpiry")] [JsonDerivedType(typeof(PollExpiryJobData), "pollExpiry")]
[JsonDerivedType(typeof(MuteExpiryJobData), "muteExpiry")] [JsonDerivedType(typeof(MuteExpiryJobData), "muteExpiry")]
[JsonDerivedType(typeof(FilterExpiryJobData), "filterExpiry")] [JsonDerivedType(typeof(FilterExpiryJobData), "filterExpiry")]
[JsonDerivedType(typeof(UserDeleteJobData), "userDelete")]
public abstract class BackgroundTaskJobData; public abstract class BackgroundTaskJobData;
public class DriveFileDeleteJobData : BackgroundTaskJobData public class DriveFileDeleteJobData : BackgroundTaskJobData
@ -240,4 +290,9 @@ public class MuteExpiryJobData : BackgroundTaskJobData
public class FilterExpiryJobData : BackgroundTaskJobData public class FilterExpiryJobData : BackgroundTaskJobData
{ {
[JR] [J("filterId")] public required long FilterId { get; set; } [JR] [J("filterId")] public required long FilterId { get; set; }
}
public class UserDeleteJobData : BackgroundTaskJobData
{
[JR] [J("userId")] public required string UserId { get; set; }
} }

View file

@ -459,10 +459,7 @@ public class UserService(
public async Task DeleteUserAsync(ASActor actor) public async Task DeleteUserAsync(ASActor actor)
{ {
var user = await db.Users var user = await db.Users.FirstOrDefaultAsync(p => p.Uri == actor.Id && p.Host != null);
.Include(user => user.Avatar)
.Include(user => user.Banner)
.FirstOrDefaultAsync(p => p.Uri == actor.Id && p.Host != null);
if (user == null) if (user == null)
{ {
@ -470,22 +467,7 @@ public class UserService(
return; return;
} }
db.Remove(user); await queueSvc.BackgroundTaskQueue.EnqueueAsync(new UserDeleteJobData { UserId = user.Id });
await db.SaveChangesAsync();
_ = followupTaskSvc.ExecuteTask("UpdateInstanceUserCounter", async provider =>
{
var bgDb = provider.GetRequiredService<DatabaseContext>();
var bgInstanceSvc = provider.GetRequiredService<InstanceService>();
var dbInstance = await bgInstanceSvc.GetUpdatedInstanceMetadataAsync(user);
await bgDb.Instances.Where(p => p.Id == dbInstance.Id)
.ExecuteUpdateAsync(p => p.SetProperty(i => i.UsersCount, i => i.UsersCount - 1));
});
if (user.Avatar != null)
await driveSvc.RemoveFile(user.Avatar);
if (user.Banner != null)
await driveSvc.RemoveFile(user.Banner);
} }
public void UpdateOauthTokenMetadata(OauthToken token) public void UpdateOauthTokenMetadata(OauthToken token)