Skip to content

Commit

Permalink
refactor: simplify the code of reconciler for comment and optimize pe…
Browse files Browse the repository at this point in the history
…rformance (#5504)

#### What type of PR is this?
/kind improvement
/area core
/milestone 2.14.x

#### What this PR does / why we need it:
优化评论控制器的实现逻辑以优化代码和性能

Resolves #5435 

how to test it?
- 测试删除评论时能正确连同回复一起删除
- 测试评论下的最新回复的已读功能是否正确
- 删除/审核评论,观察主题端和Console端分别显示的评论数量是否正确

#### Does this PR introduce a user-facing change?
```release-note
None
```
  • Loading branch information
guqing committed Mar 15, 2024
1 parent 0435e42 commit 7c3f8b9
Show file tree
Hide file tree
Showing 15 changed files with 225 additions and 239 deletions.
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package run.halo.app.content.comment;

import org.springframework.lang.NonNull;
import reactor.core.publisher.Mono;
import run.halo.app.core.extension.content.Comment;
import run.halo.app.extension.ListResult;
import run.halo.app.extension.Ref;

/**
* An application service for {@link Comment}.
Expand All @@ -15,4 +17,6 @@ public interface CommentService {
Mono<ListResult<ListedComment>> listComment(CommentQuery query);

Mono<Comment> create(Comment comment);

Mono<Void> removeBySubject(@NonNull Ref subjectRef);
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
package run.halo.app.content.comment;

import static run.halo.app.extension.index.query.QueryFactory.and;
import static run.halo.app.extension.index.query.QueryFactory.equal;
import static run.halo.app.extension.index.query.QueryFactory.isNull;

import java.time.Instant;
import java.util.function.Function;
import org.apache.commons.lang3.BooleanUtils;
import org.springframework.data.domain.Sort;
import org.springframework.lang.NonNull;
import org.springframework.security.core.context.ReactiveSecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
Expand All @@ -12,9 +18,13 @@
import run.halo.app.core.extension.content.Comment;
import run.halo.app.core.extension.service.UserService;
import run.halo.app.extension.Extension;
import run.halo.app.extension.ListOptions;
import run.halo.app.extension.ListResult;
import run.halo.app.extension.PageRequest;
import run.halo.app.extension.PageRequestImpl;
import run.halo.app.extension.ReactiveExtensionClient;
import run.halo.app.extension.Ref;
import run.halo.app.extension.router.selector.FieldSelector;
import run.halo.app.infra.SystemConfigurableEnvironmentFetcher;
import run.halo.app.infra.exception.AccessDeniedException;
import run.halo.app.metrics.CounterService;
Expand Down Expand Up @@ -114,6 +124,31 @@ public Mono<Comment> create(Comment comment) {
.flatMap(client::create);
}

@Override
public Mono<Void> removeBySubject(@NonNull Ref subjectRef) {
Assert.notNull(subjectRef, "The subjectRef must not be null.");
// ascending order by creation time and name
var pageRequest = PageRequestImpl.of(1, 200,
Sort.by("metadata.creationTimestamp", "metadata.name"));
return Flux.defer(() -> listCommentsByRef(subjectRef, pageRequest))
.expand(page -> page.hasNext()
? listCommentsByRef(subjectRef, pageRequest)
: Mono.empty()
)
.flatMap(page -> Flux.fromIterable(page.getItems()))
.flatMap(client::delete)
.then();
}

Mono<ListResult<Comment>> listCommentsByRef(Ref subjectRef, PageRequest pageRequest) {
var listOptions = new ListOptions();
listOptions.setFieldSelector(FieldSelector.of(
and(equal("spec.subjectRef", Comment.toSubjectRefKey(subjectRef)),
isNull("metadata.deletionTimestamp"))
));
return client.listBy(Comment.class, listOptions, pageRequest);
}

private boolean checkCommentOwner(Comment comment, Boolean onlySystemUser) {
Comment.CommentOwner owner = comment.getSpec().getOwner();
if (Boolean.TRUE.equals(onlySystemUser)) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
package run.halo.app.content.comment;

import java.time.Instant;
import java.util.Comparator;
import java.util.function.Function;
import org.springframework.util.comparator.Comparators;
import reactor.core.publisher.Mono;
import run.halo.app.core.extension.content.Reply;
import run.halo.app.extension.ListResult;
Expand All @@ -20,19 +16,5 @@ public interface ReplyService {

Mono<ListResult<ListedReply>> list(ReplyQuery query);

/**
* Ascending order by creation time.
*
* @return reply comparator
*/
static Comparator<Reply> creationTimeAscComparator() {
Function<Reply, Instant> creationTime = reply -> reply.getSpec().getCreationTime();
Function<Reply, Instant> metadataCreationTime =
reply -> reply.getMetadata().getCreationTimestamp();
// ascending order by creation time
// asc nulls high will be placed at the end
return Comparator.comparing(creationTime, Comparators.nullsHigh())
.thenComparing(metadataCreationTime)
.thenComparing(reply -> reply.getMetadata().getName());
}
Mono<Void> removeAllByComment(String commentName);
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
package run.halo.app.content.comment;

import static run.halo.app.extension.index.query.QueryFactory.and;
import static run.halo.app.extension.index.query.QueryFactory.equal;
import static run.halo.app.extension.index.query.QueryFactory.isNull;
import static run.halo.app.extension.router.selector.SelectorUtil.labelAndFieldSelectorToPredicate;

import java.time.Instant;
import java.util.function.Function;
import java.util.function.Predicate;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.BooleanUtils;
import org.springframework.data.domain.Sort;
import org.springframework.security.core.context.ReactiveSecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
Expand All @@ -17,8 +21,12 @@
import run.halo.app.core.extension.content.Reply;
import run.halo.app.core.extension.service.UserService;
import run.halo.app.extension.Extension;
import run.halo.app.extension.ListOptions;
import run.halo.app.extension.ListResult;
import run.halo.app.extension.PageRequest;
import run.halo.app.extension.PageRequestImpl;
import run.halo.app.extension.ReactiveExtensionClient;
import run.halo.app.extension.router.selector.FieldSelector;
import run.halo.app.metrics.CounterService;
import run.halo.app.metrics.MeterUtils;

Expand Down Expand Up @@ -89,6 +97,31 @@ public Mono<ListResult<ListedReply>> list(ReplyQuery query) {
);
}

@Override
public Mono<Void> removeAllByComment(String commentName) {
Assert.notNull(commentName, "The commentName must not be null.");
// ascending order by creation time and name
var pageRequest = PageRequestImpl.of(1, 200,
Sort.by("metadata.creationTimestamp", "metadata.name"));
return Flux.defer(() -> listRepliesByComment(commentName, pageRequest))
.expand(page -> page.hasNext()
? listRepliesByComment(commentName, pageRequest)
: Mono.empty()
)
.flatMap(page -> Flux.fromIterable(page.getItems()))
.flatMap(client::delete)
.then();
}

Mono<ListResult<Reply>> listRepliesByComment(String commentName, PageRequest pageRequest) {
var listOptions = new ListOptions();
listOptions.setFieldSelector(FieldSelector.of(
and(equal("spec.commentName", commentName),
isNull("metadata.deletionTimestamp"))
));
return client.listBy(Reply.class, listOptions, pageRequest);
}

private Mono<ListedReply> toListedReply(Reply reply) {
ListedReply.ListedReplyBuilder builder = ListedReply.builder()
.reply(reply);
Expand Down
Loading

0 comments on commit 7c3f8b9

Please sign in to comment.