fix: deadlock on user deletion — webhook handler never checked intentional mark

mark_intentional_panel_deletion was called before api.delete_user,
but _is_intentional_panel_deletion_event was never called in the
webhook handler — it was dead code. The user.deleted webhook processed
unconditionally, causing a deadlock between delete_user_account (Tx1
holding subscription row locks) and the webhook handler (Tx2 trying
to lock the same rows via decrement_subscription_server_counts).

Fix: check _is_intentional_panel_deletion_event at the top of
_handle_user_deleted — if True, log and return immediately without
touching the DB.
This commit is contained in:
Fringg
2026-04-29 10:28:57 +03:00
parent c905fa6000
commit 62e7ecba01
+10
View File
@@ -994,6 +994,16 @@ class RemnaWaveWebhookService:
async def _handle_user_deleted(
self, db: AsyncSession, user: User, subscription: Subscription | None, data: dict
) -> None:
# Suppress webhook if this deletion was initiated by delete_user_account —
# prevents deadlock between the ongoing deletion transaction and this handler
if self._is_intentional_panel_deletion_event(data):
logger.info(
'Webhook user.deleted suppressed — intentional panel deletion in progress',
user_id=user.id,
uuid=data.get('uuid'),
)
return
user_id = user.id
sub_id = subscription.id if subscription else None