Run bank sync in background to avoid gateway timeouts
sync-now and sync-all now return 202 Accepted immediately and dispatch work to a background task. The frontend uses the existing SignalR BankSyncComplete notification to stop the spinner and display results. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -12,9 +12,16 @@ namespace Purrse.Api.Controllers;
|
||||
public class BankSyncController : ControllerBase
|
||||
{
|
||||
private readonly IBankSyncService _bankSyncService;
|
||||
private readonly IServiceScopeFactory _scopeFactory;
|
||||
private readonly ILogger<BankSyncController> _logger;
|
||||
private Guid UserId => Guid.Parse(User.FindFirstValue(ClaimTypes.NameIdentifier)!);
|
||||
|
||||
public BankSyncController(IBankSyncService bankSyncService) => _bankSyncService = bankSyncService;
|
||||
public BankSyncController(IBankSyncService bankSyncService, IServiceScopeFactory scopeFactory, ILogger<BankSyncController> logger)
|
||||
{
|
||||
_bankSyncService = bankSyncService;
|
||||
_scopeFactory = scopeFactory;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
[HttpGet("connections")]
|
||||
public async Task<ActionResult<List<SyncConnectionResponse>>> GetConnections()
|
||||
@@ -68,12 +75,32 @@ public class BankSyncController : ControllerBase
|
||||
=> Ok(await _bankSyncService.UpdateLinkedAccountAsync(UserId, id, request));
|
||||
|
||||
[HttpPost("connections/{id}/sync-now")]
|
||||
public async Task<ActionResult<SyncResultResponse>> SyncNow(Guid id)
|
||||
=> Ok(await _bankSyncService.SyncNowAsync(UserId, id));
|
||||
public IActionResult SyncNow(Guid id)
|
||||
{
|
||||
var userId = UserId;
|
||||
_ = Task.Run(async () =>
|
||||
{
|
||||
using var scope = _scopeFactory.CreateScope();
|
||||
var service = scope.ServiceProvider.GetRequiredService<IBankSyncService>();
|
||||
try { await service.SyncNowAsync(userId, id); }
|
||||
catch (Exception ex) { _logger.LogError(ex, "Background sync failed for connection {Id}", id); }
|
||||
});
|
||||
return Accepted();
|
||||
}
|
||||
|
||||
[HttpPost("sync-all")]
|
||||
public async Task<ActionResult<SyncResultResponse>> SyncAll()
|
||||
=> Ok(await _bankSyncService.SyncAllAsync(UserId));
|
||||
public IActionResult SyncAll()
|
||||
{
|
||||
var userId = UserId;
|
||||
_ = Task.Run(async () =>
|
||||
{
|
||||
using var scope = _scopeFactory.CreateScope();
|
||||
var service = scope.ServiceProvider.GetRequiredService<IBankSyncService>();
|
||||
try { await service.SyncAllAsync(userId); }
|
||||
catch (Exception ex) { _logger.LogError(ex, "Background sync-all failed for user {UserId}", userId); }
|
||||
});
|
||||
return Accepted();
|
||||
}
|
||||
|
||||
[HttpGet("sync-logs")]
|
||||
public async Task<ActionResult<List<SyncLogResponse>>> GetSyncLogs([FromQuery] Guid? connectionId, [FromQuery] int limit = 50)
|
||||
|
||||
Reference in New Issue
Block a user