diff options
author | Joas Schilling <coding@schilljs.com> | 2025-05-30 08:53:18 +0200 |
---|---|---|
committer | Joas Schilling <coding@schilljs.com> | 2025-05-30 08:53:18 +0200 |
commit | f3a26c5f8965ba138d8713d767ed8b6e4df63172 (patch) | |
tree | 9264a5d17f641cded3e8d9364225b506c2e4f1a0 | |
parent | 52299ba9f6d669adbd84db3bd98b67b68e6dbe93 (diff) | |
download | nextcloud-server-bugfix/noid/user_status-unique-constraint.tar.gz nextcloud-server-bugfix/noid/user_status-unique-constraint.zip |
fix(user_status): Avoid unique constraint violations from parallel heartbeats and GET requestsbugfix/noid/user_status-unique-constraint
Signed-off-by: Joas Schilling <coding@schilljs.com>
-rw-r--r-- | apps/user_status/lib/Service/StatusService.php | 20 |
1 files changed, 16 insertions, 4 deletions
diff --git a/apps/user_status/lib/Service/StatusService.php b/apps/user_status/lib/Service/StatusService.php index 9adc13e4dbf..188eb26d1d7 100644 --- a/apps/user_status/lib/Service/StatusService.php +++ b/apps/user_status/lib/Service/StatusService.php @@ -167,7 +167,7 @@ class StatusService { $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 @@ class StatusService { $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 @@ class StatusService { if ($userStatus->getId() !== null) { return $this->mapper->update($userStatus); } - return $this->mapper->insert($userStatus); + return $this->insertWithoutThrowingUniqueConstrain($userStatus); } /** @@ -360,7 +360,7 @@ class StatusService { $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 @@ class StatusService { // 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; + } } |