[backend/core] Update user in background to avoid accessing a disposed DbContext
This commit is contained in:
parent
19b004687d
commit
b3d0c0f476
3 changed files with 37 additions and 3 deletions
|
@ -22,7 +22,7 @@ public static class ServiceExtensions
|
|||
public static void AddServices(this IServiceCollection services)
|
||||
{
|
||||
// Transient = instantiated per request and class
|
||||
//services.AddTransient<T>();
|
||||
services.AddTransient<FollowupTaskService>();
|
||||
|
||||
// Scoped = instantiated per request
|
||||
services
|
||||
|
|
|
@ -5,7 +5,12 @@ using Iceshrimp.Backend.Core.Services;
|
|||
|
||||
namespace Iceshrimp.Backend.Core.Federation.ActivityPub;
|
||||
|
||||
public class UserResolver(ILogger<UserResolver> logger, UserService userSvc, WebFingerService webFingerSvc)
|
||||
public class UserResolver(
|
||||
ILogger<UserResolver> logger,
|
||||
UserService userSvc,
|
||||
WebFingerService webFingerSvc,
|
||||
FollowupTaskService followupTaskSvc
|
||||
)
|
||||
{
|
||||
/*
|
||||
* The full web finger algorithm:
|
||||
|
@ -110,7 +115,14 @@ public class UserResolver(ILogger<UserResolver> logger, UserService userSvc, Web
|
|||
|
||||
try
|
||||
{
|
||||
return await userSvc.UpdateUserAsync(user).WaitAsync(TimeSpan.FromMilliseconds(1500));
|
||||
var task = followupTaskSvc.ExecuteTask("UpdateUserAsync", async provider =>
|
||||
{
|
||||
var bgUserSvc = provider.GetRequiredService<UserService>();
|
||||
await bgUserSvc.UpdateUserAsync(user);
|
||||
});
|
||||
|
||||
// Return early, but continue execution in background
|
||||
await task.WaitAsync(TimeSpan.FromMilliseconds(1500));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
|
22
Iceshrimp.Backend/Core/Services/FollowupTaskService.cs
Normal file
22
Iceshrimp.Backend/Core/Services/FollowupTaskService.cs
Normal file
|
@ -0,0 +1,22 @@
|
|||
namespace Iceshrimp.Backend.Core.Services;
|
||||
|
||||
public class FollowupTaskService(IServiceScopeFactory serviceScopeFactory)
|
||||
{
|
||||
public Task ExecuteTask(string taskName, Func<IServiceProvider, Task> work)
|
||||
{
|
||||
return Task.Run(async () =>
|
||||
{
|
||||
using var scope = serviceScopeFactory.CreateScope();
|
||||
try
|
||||
{
|
||||
var provider = scope.ServiceProvider;
|
||||
await work(provider);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
var logger = scope.ServiceProvider.GetRequiredService<ILogger<FollowupTaskService>>();
|
||||
logger.LogError("Failed to execute background task {name}: {error}", taskName, e.ToString());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue