api: delete repositories asynchronously

Currently, a request to delete a repository is blocked until the
repository is completely removed from the filesystem. When CephFS is
under load and a user deletes a large-ish repo, this can cause signicant
request latency, making the user abort the request or even timing out
completely. The context gets canceled, causing the transaction to roll
back, even though the data is eventually wiped completely from storage,
leaving users with broken repositories on their profile.

Instead, simply do the deletion from storage asynchronously, so that the
user gets instant feedback. Even though the deletion itself blocks for
potentially a long time, experience has shown that it finishes even in
case of cancellation. As such, I expect that the deletion will go
through even if the go-routine were to be aborted (e.g. by a restart of
the API).
This commit is contained in:
Conrad Hoffmann 2024-03-27 11:25:10 +01:00 committed by Drew DeVault
parent 1dd572a814
commit 8a40a82b96
1 changed files with 5 additions and 3 deletions

View File

@ -476,9 +476,11 @@ func (r *mutationResolver) DeleteRepository(ctx context.Context, id int) (*model
webhooks.DeliverRepoEvent(ctx, model.WebhookEventRepoDeleted, &repo)
webhooks.DeliverLegacyRepoDeleted(ctx, &repo)
if err := os.RemoveAll(repo.Path); err != nil {
return err
}
go func(ctx context.Context, path string) {
if err := os.RemoveAll(path); err != nil {
server.EmailRecover(ctx, err)
}
}(context.WithoutCancel(ctx), repo.Path)
if len(artifacts) > 0 {
username := auth.ForContext(ctx).Username