[backend/core] Don't share entities between DbContext instances
This commit is contained in:
parent
a8c903cee7
commit
2d92d27dbf
2 changed files with 16 additions and 7 deletions
|
@ -1,9 +1,12 @@
|
|||
using AsyncKeyedLock;
|
||||
using Iceshrimp.Backend.Core.Configuration;
|
||||
using Iceshrimp.Backend.Core.Database;
|
||||
using Iceshrimp.Backend.Core.Database.Tables;
|
||||
using Iceshrimp.Backend.Core.Extensions;
|
||||
using Iceshrimp.Backend.Core.Federation.WebFinger;
|
||||
using Iceshrimp.Backend.Core.Middleware;
|
||||
using Iceshrimp.Backend.Core.Services;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace Iceshrimp.Backend.Core.Federation.ActivityPub;
|
||||
|
@ -13,7 +16,8 @@ public class UserResolver(
|
|||
UserService userSvc,
|
||||
WebFingerService webFingerSvc,
|
||||
FollowupTaskService followupTaskSvc,
|
||||
IOptions<Config.InstanceSection> config
|
||||
IOptions<Config.InstanceSection> config,
|
||||
DatabaseContext db
|
||||
)
|
||||
{
|
||||
private static readonly AsyncKeyedLocker<string> KeyedLocker = new(o =>
|
||||
|
@ -207,6 +211,8 @@ public class UserResolver(
|
|||
if (!user.NeedsUpdate) return user;
|
||||
user.LastFetchedAt = DateTime.UtcNow; // Prevent multiple background tasks from being started
|
||||
|
||||
var success = false;
|
||||
|
||||
try
|
||||
{
|
||||
var task = followupTaskSvc.ExecuteTask("UpdateUserAsync", async provider =>
|
||||
|
@ -215,8 +221,8 @@ public class UserResolver(
|
|||
var bgUserSvc = provider.GetRequiredService<UserService>();
|
||||
|
||||
// Use the id overload so it doesn't attempt to insert in the main thread's DbContext
|
||||
var fetchedUser = await bgUserSvc.UpdateUserAsync(user.Id);
|
||||
user = fetchedUser;
|
||||
await bgUserSvc.UpdateUserAsync(user.Id);
|
||||
success = true;
|
||||
});
|
||||
|
||||
// Return early, but continue execution in background
|
||||
|
@ -230,6 +236,6 @@ public class UserResolver(
|
|||
logger.LogError("UpdateUserAsync for user {user} failed with {error}", user.Uri, e.Message);
|
||||
}
|
||||
|
||||
return user;
|
||||
return success ? await db.Users.IncludeCommonProperties().FirstAsync(p => p.Id == user.Id) : user;
|
||||
}
|
||||
}
|
|
@ -731,6 +731,8 @@ public class UserService(
|
|||
if (followupTaskSvc.IsBackgroundWorker && !force) return user;
|
||||
if (KeyedLocker.IsInUse($"profileMentions:{user.Id}")) return user;
|
||||
|
||||
var success = false;
|
||||
|
||||
var task = followupTaskSvc.ExecuteTask("UpdateProfileMentionsInBackground", async provider =>
|
||||
{
|
||||
using (await KeyedLocker.LockAsync($"profileMentions:{user.Id}"))
|
||||
|
@ -773,11 +775,12 @@ public class UserService(
|
|||
bgUser.UserProfile.MentionsResolved = true;
|
||||
bgDbContext.Update(bgUser.UserProfile);
|
||||
await bgDbContext.SaveChangesAsync();
|
||||
user = bgUser;
|
||||
success = true;
|
||||
}
|
||||
});
|
||||
|
||||
await task.SafeWaitAsync(TimeSpan.FromMilliseconds(500));
|
||||
return user;
|
||||
|
||||
return success ? await db.Users.IncludeCommonProperties().FirstAsync(p => p.Id == user.Id) : user;
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue