From 867d86b1a77c734245ebdff2b504411d83df8062 Mon Sep 17 00:00:00 2001 From: guqing <38999863+guqing@users.noreply.github.com> Date: Wed, 27 Mar 2024 21:22:07 +0800 Subject: [PATCH] refactor: reduce the number of failures due to conflict post update (#5604) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #### What type of PR is this? /kind improvement /area core /milestone 2.14.x #### What this PR does / why we need it: 减少文章更新因版本号冲突而失败的次数 #### Which issue(s) this PR fixes: Fixes #5579 #### Does this PR introduce a user-facing change? ```release-note None ``` --- .../app/content/AbstractContentService.java | 30 +++++++++++-------- .../app/content/impl/PostServiceImpl.java | 12 ++++---- .../content/impl/SinglePageServiceImpl.java | 12 ++++---- .../core/extension/endpoint/PostEndpoint.java | 12 ++++---- .../endpoint/SinglePageEndpoint.java | 12 ++++---- 5 files changed, 42 insertions(+), 36 deletions(-) diff --git a/application/src/main/java/run/halo/app/content/AbstractContentService.java b/application/src/main/java/run/halo/app/content/AbstractContentService.java index 7b971b7301..530cd72bff 100644 --- a/application/src/main/java/run/halo/app/content/AbstractContentService.java +++ b/application/src/main/java/run/halo/app/content/AbstractContentService.java @@ -1,16 +1,19 @@ package run.halo.app.content; import java.security.Principal; +import java.time.Duration; import java.time.Instant; import java.util.UUID; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; +import org.springframework.dao.OptimisticLockingFailureException; import org.springframework.lang.Nullable; import org.springframework.security.core.context.ReactiveSecurityContextHolder; import org.springframework.security.core.context.SecurityContext; import org.springframework.util.Assert; import reactor.core.publisher.Mono; +import reactor.util.retry.Retry; import run.halo.app.core.extension.content.Snapshot; import run.halo.app.extension.MetadataUtil; import run.halo.app.extension.ReactiveExtensionClient; @@ -94,20 +97,23 @@ protected Mono updateContent(String baseSnapshotName, Assert.notNull(contentRequest, "The contentRequest must not be null"); Assert.notNull(baseSnapshotName, "The baseSnapshotName must not be null"); Assert.notNull(contentRequest.headSnapshotName(), "The headSnapshotName must not be null"); - return client.fetch(Snapshot.class, contentRequest.headSnapshotName()) - .flatMap(headSnapshot -> client.fetch(Snapshot.class, baseSnapshotName) - .map(baseSnapshot -> determineRawAndContentPatch(headSnapshot, baseSnapshot, - contentRequest) + return Mono.defer(() -> client.fetch(Snapshot.class, contentRequest.headSnapshotName()) + .flatMap(headSnapshot -> client.fetch(Snapshot.class, baseSnapshotName) + .map(baseSnapshot -> determineRawAndContentPatch(headSnapshot, baseSnapshot, + contentRequest) + ) ) + .flatMap(headSnapshot -> getContextUsername() + .map(username -> { + Snapshot.addContributor(headSnapshot, username); + return headSnapshot; + }) + .defaultIfEmpty(headSnapshot) + ) + .flatMap(client::update) ) - .flatMap(headSnapshot -> getContextUsername() - .map(username -> { - Snapshot.addContributor(headSnapshot, username); - return headSnapshot; - }) - .defaultIfEmpty(headSnapshot) - ) - .flatMap(client::update) + .retryWhen(Retry.backoff(5, Duration.ofMillis(100)) + .filter(throwable -> throwable instanceof OptimisticLockingFailureException)) .flatMap(head -> restoredContent(baseSnapshotName, head)); } diff --git a/application/src/main/java/run/halo/app/content/impl/PostServiceImpl.java b/application/src/main/java/run/halo/app/content/impl/PostServiceImpl.java index 8a26c0bcbd..8448ea51bf 100644 --- a/application/src/main/java/run/halo/app/content/impl/PostServiceImpl.java +++ b/application/src/main/java/run/halo/app/content/impl/PostServiceImpl.java @@ -225,13 +225,11 @@ public Mono updatePost(PostRequest postRequest) { return client.update(post); }); } - return Mono.defer(() -> updateContent(baseSnapshot, postRequest.contentRequest()) - .flatMap(contentWrapper -> { - post.getSpec().setHeadSnapshot(contentWrapper.getSnapshotName()); - return client.update(post); - })) - .retryWhen(Retry.backoff(5, Duration.ofMillis(100)) - .filter(throwable -> throwable instanceof OptimisticLockingFailureException)); + return updateContent(baseSnapshot, postRequest.contentRequest()) + .flatMap(contentWrapper -> { + post.getSpec().setHeadSnapshot(contentWrapper.getSnapshotName()); + return client.update(post); + }); } @Override diff --git a/application/src/main/java/run/halo/app/content/impl/SinglePageServiceImpl.java b/application/src/main/java/run/halo/app/content/impl/SinglePageServiceImpl.java index 753cbcf20a..6cfe474ced 100644 --- a/application/src/main/java/run/halo/app/content/impl/SinglePageServiceImpl.java +++ b/application/src/main/java/run/halo/app/content/impl/SinglePageServiceImpl.java @@ -156,13 +156,11 @@ public Mono update(SinglePageRequest pageRequest) { return client.update(page); }); } - return Mono.defer(() -> updateContent(baseSnapshot, pageRequest.contentRequest()) - .flatMap(contentWrapper -> { - page.getSpec().setHeadSnapshot(contentWrapper.getSnapshotName()); - return client.update(page); - })) - .retryWhen(Retry.backoff(5, Duration.ofMillis(100)) - .filter(throwable -> throwable instanceof OptimisticLockingFailureException)); + return updateContent(baseSnapshot, pageRequest.contentRequest()) + .flatMap(contentWrapper -> { + page.getSpec().setHeadSnapshot(contentWrapper.getSnapshotName()); + return client.update(page); + }); } private Mono getListedSinglePage(SinglePage singlePage) { diff --git a/application/src/main/java/run/halo/app/core/extension/endpoint/PostEndpoint.java b/application/src/main/java/run/halo/app/core/extension/endpoint/PostEndpoint.java index 559afb512b..0f1273a894 100644 --- a/application/src/main/java/run/halo/app/core/extension/endpoint/PostEndpoint.java +++ b/application/src/main/java/run/halo/app/core/extension/endpoint/PostEndpoint.java @@ -193,11 +193,13 @@ Mono draftPost(ServerRequest request) { Mono updateContent(ServerRequest request) { String postName = request.pathVariable("name"); return request.bodyToMono(Content.class) - .flatMap(content -> client.fetch(Post.class, postName) - .flatMap(post -> { - PostRequest postRequest = new PostRequest(post, content); - return postService.updatePost(postRequest); - }) + .flatMap(content -> Mono.defer(() -> client.fetch(Post.class, postName) + .flatMap(post -> { + PostRequest postRequest = new PostRequest(post, content); + return postService.updatePost(postRequest); + })) + .retryWhen(Retry.backoff(5, Duration.ofMillis(100)) + .filter(throwable -> throwable instanceof OptimisticLockingFailureException)) ) .flatMap(post -> ServerResponse.ok().bodyValue(post)); } diff --git a/application/src/main/java/run/halo/app/core/extension/endpoint/SinglePageEndpoint.java b/application/src/main/java/run/halo/app/core/extension/endpoint/SinglePageEndpoint.java index 1952d62b51..4be776a021 100644 --- a/application/src/main/java/run/halo/app/core/extension/endpoint/SinglePageEndpoint.java +++ b/application/src/main/java/run/halo/app/core/extension/endpoint/SinglePageEndpoint.java @@ -171,11 +171,13 @@ Mono draftSinglePage(ServerRequest request) { Mono updateContent(ServerRequest request) { String pageName = request.pathVariable("name"); return request.bodyToMono(Content.class) - .flatMap(content -> client.fetch(SinglePage.class, pageName) - .flatMap(page -> { - SinglePageRequest pageRequest = new SinglePageRequest(page, content); - return singlePageService.update(pageRequest); - }) + .flatMap(content -> Mono.defer(() -> client.fetch(SinglePage.class, pageName) + .flatMap(page -> { + SinglePageRequest pageRequest = new SinglePageRequest(page, content); + return singlePageService.update(pageRequest); + })) + .retryWhen(Retry.backoff(5, Duration.ofMillis(100)) + .filter(throwable -> throwable instanceof OptimisticLockingFailureException)) ) .flatMap(post -> ServerResponse.ok().bodyValue(post)); }