Best effort connector delete

Signed-off-by: Bryan Frimin <bryan@probo.com>
This commit is contained in:
Bryan Frimin
2026-05-28 12:20:57 -07:00
parent d579879707
commit 0161b21120
2 changed files with 25 additions and 3 deletions

View File

@@ -261,11 +261,27 @@ func (s AccessSourceService) Delete(
return nil return nil
} }
// Garbage-collecting the connector is best-effort. A
// concurrent transaction may insert a new access source or
// SCIM bridge referencing this connector between the counts
// above and the DELETE, producing a foreign-key violation.
// Run the delete inside a savepoint so such a failure rolls
// back only the GC attempt and still commits the access
// source deletion instead of aborting the whole transaction.
if err := conn.Savepoint(
ctx,
func(ctx context.Context, conn pg.Tx) error {
cnnctr := &coredata.Connector{ID: *source.ConnectorID} cnnctr := &coredata.Connector{ID: *source.ConnectorID}
if err := cnnctr.Delete(ctx, conn, s.scope); err != nil { if err := cnnctr.Delete(ctx, conn, s.scope); err != nil {
return fmt.Errorf("cannot delete connector: %w", err) return fmt.Errorf("cannot delete connector: %w", err)
} }
return nil
},
); err != nil {
return err
}
return nil return nil
}, },
) )

View File

@@ -322,6 +322,12 @@ WHERE %s AND id = @id
_, err := conn.Exec(ctx, q, args) _, err := conn.Exec(ctx, q, args)
if err != nil { if err != nil {
if pgErr, ok := errors.AsType[*pgconn.PgError](err); ok {
if pgErr.Code == "23503" {
return ErrResourceInUse
}
}
return fmt.Errorf("cannot delete connector: %w", err) return fmt.Errorf("cannot delete connector: %w", err)
} }