From 4c83a8b75a92a7ef9cf3a3c0a40ba98a6b249360 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Fri, 30 May 2025 08:53:18 +0200 Subject: [PATCH] fix(user_status): Avoid unique constraint violations from parallel heartbeats and GET requests Signed-off-by: Joas Schilling --- .../user_status/lib/Service/StatusService.php | 20 +++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/apps/user_status/lib/Service/StatusService.php b/apps/user_status/lib/Service/StatusService.php index 9adc13e4dbf83..188eb26d1d7a9 100644 --- a/apps/user_status/lib/Service/StatusService.php +++ b/apps/user_status/lib/Service/StatusService.php @@ -167,7 +167,7 @@ public function setStatus(string $userId, $userStatus->setIsBackup(false); if ($userStatus->getId() === null) { - return $this->mapper->insert($userStatus); + return $this->insertWithoutThrowingUniqueConstrain($userStatus); } return $this->mapper->update($userStatus); @@ -211,7 +211,7 @@ public function setPredefinedMessage(string $userId, $userStatus->setStatusMessageTimestamp($this->timeFactory->now()->getTimestamp()); if ($userStatus->getId() === null) { - return $this->mapper->insert($userStatus); + return $this->insertWithoutThrowingUniqueConstrain($userStatus); } return $this->mapper->update($userStatus); @@ -313,7 +313,7 @@ public function setUserStatus(string $userId, if ($userStatus->getId() !== null) { return $this->mapper->update($userStatus); } - return $this->mapper->insert($userStatus); + return $this->insertWithoutThrowingUniqueConstrain($userStatus); } /** @@ -360,7 +360,7 @@ public function setCustomMessage(string $userId, $userStatus->setStatusMessageTimestamp($this->timeFactory->now()->getTimestamp()); if ($userStatus->getId() === null) { - return $this->mapper->insert($userStatus); + return $this->insertWithoutThrowingUniqueConstrain($userStatus); } return $this->mapper->update($userStatus); @@ -584,4 +584,16 @@ public function revertMultipleUserStatus(array $userIds, string $messageId): voi // For users that matched restore the previous status $this->mapper->restoreBackupStatuses($restoreIds); } + + protected function insertWithoutThrowingUniqueConstrain(UserStatus $userStatus): UserStatus { + try { + return $this->mapper->insert($userStatus); + } catch (Exception $e) { + // Ignore if a parallel request already set the status + if ($e->getReason() !== Exception::REASON_UNIQUE_CONSTRAINT_VIOLATION) { + throw $e; + } + } + return $userStatus; + } }