mirror of https://github.com/halo-dev/halo
refactor: reduce the number of failures due to conflict post update (#5604)
#### 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 ```pull/5626/head v2.14.0-rc.1
parent
ec4c390e1f
commit
867d86b1a7
|
@ -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,7 +97,7 @@ public abstract class AbstractContentService {
|
|||
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())
|
||||
return Mono.defer(() -> client.fetch(Snapshot.class, contentRequest.headSnapshotName())
|
||||
.flatMap(headSnapshot -> client.fetch(Snapshot.class, baseSnapshotName)
|
||||
.map(baseSnapshot -> determineRawAndContentPatch(headSnapshot, baseSnapshot,
|
||||
contentRequest)
|
||||
|
@ -108,6 +111,9 @@ public abstract class AbstractContentService {
|
|||
.defaultIfEmpty(headSnapshot)
|
||||
)
|
||||
.flatMap(client::update)
|
||||
)
|
||||
.retryWhen(Retry.backoff(5, Duration.ofMillis(100))
|
||||
.filter(throwable -> throwable instanceof OptimisticLockingFailureException))
|
||||
.flatMap(head -> restoredContent(baseSnapshotName, head));
|
||||
}
|
||||
|
||||
|
|
|
@ -225,13 +225,11 @@ public class PostServiceImpl extends AbstractContentService implements PostServi
|
|||
return client.update(post);
|
||||
});
|
||||
}
|
||||
return Mono.defer(() -> updateContent(baseSnapshot, postRequest.contentRequest())
|
||||
return 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));
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -156,13 +156,11 @@ public class SinglePageServiceImpl extends AbstractContentService implements Sin
|
|||
return client.update(page);
|
||||
});
|
||||
}
|
||||
return Mono.defer(() -> updateContent(baseSnapshot, pageRequest.contentRequest())
|
||||
return 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));
|
||||
});
|
||||
}
|
||||
|
||||
private Mono<ListedSinglePage> getListedSinglePage(SinglePage singlePage) {
|
||||
|
|
|
@ -193,11 +193,13 @@ public class PostEndpoint implements CustomEndpoint {
|
|||
Mono<ServerResponse> updateContent(ServerRequest request) {
|
||||
String postName = request.pathVariable("name");
|
||||
return request.bodyToMono(Content.class)
|
||||
.flatMap(content -> client.fetch(Post.class, postName)
|
||||
.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));
|
||||
}
|
||||
|
|
|
@ -171,11 +171,13 @@ public class SinglePageEndpoint implements CustomEndpoint {
|
|||
Mono<ServerResponse> updateContent(ServerRequest request) {
|
||||
String pageName = request.pathVariable("name");
|
||||
return request.bodyToMono(Content.class)
|
||||
.flatMap(content -> client.fetch(SinglePage.class, pageName)
|
||||
.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));
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue