mirror of https://github.com/halo-dev/halo
refactor: optimize comment reconciliation for better performance and efficiency (#5708)
parent
2aac668df2
commit
25339c7d14
|
@ -31,6 +31,8 @@ public class Comment extends AbstractExtension {
|
||||||
|
|
||||||
public static final String KIND = "Comment";
|
public static final String KIND = "Comment";
|
||||||
|
|
||||||
|
public static final String REQUIRE_SYNC_ON_STARTUP_INDEX_NAME = "requireSyncOnStartup";
|
||||||
|
|
||||||
@Schema(requiredMode = REQUIRED)
|
@Schema(requiredMode = REQUIRED)
|
||||||
private CommentSpec spec;
|
private CommentSpec spec;
|
||||||
|
|
||||||
|
@ -135,6 +137,8 @@ public class Comment extends AbstractExtension {
|
||||||
private Integer unreadReplyCount;
|
private Integer unreadReplyCount;
|
||||||
|
|
||||||
private Boolean hasNewReply;
|
private Boolean hasNewReply;
|
||||||
|
|
||||||
|
private Long observedVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String toSubjectRefKey(Ref subjectRef) {
|
public static String toSubjectRefKey(Ref subjectRef) {
|
||||||
|
|
|
@ -5,7 +5,9 @@ import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.REQUIRED;
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.Getter;
|
||||||
import lombok.ToString;
|
import lombok.ToString;
|
||||||
|
import org.springframework.lang.NonNull;
|
||||||
import run.halo.app.extension.AbstractExtension;
|
import run.halo.app.extension.AbstractExtension;
|
||||||
import run.halo.app.extension.GVK;
|
import run.halo.app.extension.GVK;
|
||||||
|
|
||||||
|
@ -23,9 +25,15 @@ public class Reply extends AbstractExtension {
|
||||||
|
|
||||||
public static final String KIND = "Reply";
|
public static final String KIND = "Reply";
|
||||||
|
|
||||||
|
public static final String REQUIRE_SYNC_ON_STARTUP_INDEX_NAME = "requireSyncOnStartup";
|
||||||
|
|
||||||
@Schema(requiredMode = REQUIRED)
|
@Schema(requiredMode = REQUIRED)
|
||||||
private ReplySpec spec;
|
private ReplySpec spec;
|
||||||
|
|
||||||
|
@Schema
|
||||||
|
@Getter(onMethod_ = @NonNull)
|
||||||
|
private Status status = new Status();
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
@EqualsAndHashCode(callSuper = true)
|
@EqualsAndHashCode(callSuper = true)
|
||||||
public static class ReplySpec extends Comment.BaseCommentSpec {
|
public static class ReplySpec extends Comment.BaseCommentSpec {
|
||||||
|
@ -35,4 +43,14 @@ public class Reply extends AbstractExtension {
|
||||||
|
|
||||||
private String quoteReply;
|
private String quoteReply;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Schema(name = "ReplyStatus")
|
||||||
|
public static class Status {
|
||||||
|
private Long observedVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStatus(Status status) {
|
||||||
|
this.status = status == null ? new Status() : status;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,7 @@ import run.halo.app.core.extension.content.Comment;
|
||||||
import run.halo.app.core.extension.content.Constant;
|
import run.halo.app.core.extension.content.Constant;
|
||||||
import run.halo.app.event.post.CommentCreatedEvent;
|
import run.halo.app.event.post.CommentCreatedEvent;
|
||||||
import run.halo.app.event.post.CommentUnreadReplyCountChangedEvent;
|
import run.halo.app.event.post.CommentUnreadReplyCountChangedEvent;
|
||||||
|
import run.halo.app.extension.DefaultExtensionMatcher;
|
||||||
import run.halo.app.extension.ExtensionClient;
|
import run.halo.app.extension.ExtensionClient;
|
||||||
import run.halo.app.extension.GroupVersionKind;
|
import run.halo.app.extension.GroupVersionKind;
|
||||||
import run.halo.app.extension.ListOptions;
|
import run.halo.app.extension.ListOptions;
|
||||||
|
@ -86,8 +87,15 @@ public class CommentReconciler implements Reconciler<Reconciler.Request> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Controller setupWith(ControllerBuilder builder) {
|
public Controller setupWith(ControllerBuilder builder) {
|
||||||
|
var extension = new Comment();
|
||||||
return builder
|
return builder
|
||||||
.extension(new Comment())
|
.extension(extension)
|
||||||
|
.onAddMatcher(DefaultExtensionMatcher.builder(client, extension.groupVersionKind())
|
||||||
|
.fieldSelector(FieldSelector.of(
|
||||||
|
equal(Comment.REQUIRE_SYNC_ON_STARTUP_INDEX_NAME, BooleanUtils.TRUE))
|
||||||
|
)
|
||||||
|
.build()
|
||||||
|
)
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,9 +2,11 @@ package run.halo.app.core.extension.reconciler;
|
||||||
|
|
||||||
import static org.apache.commons.lang3.ObjectUtils.defaultIfNull;
|
import static org.apache.commons.lang3.ObjectUtils.defaultIfNull;
|
||||||
import static run.halo.app.extension.ExtensionUtil.addFinalizers;
|
import static run.halo.app.extension.ExtensionUtil.addFinalizers;
|
||||||
|
import static run.halo.app.extension.index.query.QueryFactory.equal;
|
||||||
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
|
import org.apache.commons.lang3.BooleanUtils;
|
||||||
import org.springframework.context.ApplicationEventPublisher;
|
import org.springframework.context.ApplicationEventPublisher;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import run.halo.app.content.comment.ReplyNotificationSubscriptionHelper;
|
import run.halo.app.content.comment.ReplyNotificationSubscriptionHelper;
|
||||||
|
@ -12,10 +14,12 @@ import run.halo.app.core.extension.content.Reply;
|
||||||
import run.halo.app.event.post.ReplyChangedEvent;
|
import run.halo.app.event.post.ReplyChangedEvent;
|
||||||
import run.halo.app.event.post.ReplyCreatedEvent;
|
import run.halo.app.event.post.ReplyCreatedEvent;
|
||||||
import run.halo.app.event.post.ReplyDeletedEvent;
|
import run.halo.app.event.post.ReplyDeletedEvent;
|
||||||
|
import run.halo.app.extension.DefaultExtensionMatcher;
|
||||||
import run.halo.app.extension.ExtensionClient;
|
import run.halo.app.extension.ExtensionClient;
|
||||||
import run.halo.app.extension.controller.Controller;
|
import run.halo.app.extension.controller.Controller;
|
||||||
import run.halo.app.extension.controller.ControllerBuilder;
|
import run.halo.app.extension.controller.ControllerBuilder;
|
||||||
import run.halo.app.extension.controller.Reconciler;
|
import run.halo.app.extension.controller.Reconciler;
|
||||||
|
import run.halo.app.extension.router.selector.FieldSelector;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reconciler for {@link Reply}.
|
* Reconciler for {@link Reply}.
|
||||||
|
@ -76,8 +80,15 @@ public class ReplyReconciler implements Reconciler<Reconciler.Request> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Controller setupWith(ControllerBuilder builder) {
|
public Controller setupWith(ControllerBuilder builder) {
|
||||||
|
var extension = new Reply();
|
||||||
return builder
|
return builder
|
||||||
.extension(new Reply())
|
.extension(extension)
|
||||||
|
.onAddMatcher(DefaultExtensionMatcher.builder(client, extension.groupVersionKind())
|
||||||
|
.fieldSelector(FieldSelector.of(
|
||||||
|
equal(Reply.REQUIRE_SYNC_ON_STARTUP_INDEX_NAME, BooleanUtils.TRUE))
|
||||||
|
)
|
||||||
|
.build()
|
||||||
|
)
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -308,6 +308,17 @@ public class SchemeInitializer implements ApplicationListener<ApplicationContext
|
||||||
var replyCount = comment.getStatusOrDefault().getReplyCount();
|
var replyCount = comment.getStatusOrDefault().getReplyCount();
|
||||||
return defaultIfNull(replyCount, 0).toString();
|
return defaultIfNull(replyCount, 0).toString();
|
||||||
})));
|
})));
|
||||||
|
indexSpecs.add(new IndexSpec()
|
||||||
|
.setName(Comment.REQUIRE_SYNC_ON_STARTUP_INDEX_NAME)
|
||||||
|
.setIndexFunc(simpleAttribute(Comment.class, comment -> {
|
||||||
|
var version = comment.getMetadata().getVersion();
|
||||||
|
var observedVersion = comment.getStatusOrDefault().getObservedVersion();
|
||||||
|
if (observedVersion == null || observedVersion < version) {
|
||||||
|
return BooleanUtils.TRUE;
|
||||||
|
}
|
||||||
|
// do not care about the false case so return null to avoid indexing
|
||||||
|
return null;
|
||||||
|
})));
|
||||||
});
|
});
|
||||||
schemeManager.register(Reply.class, indexSpecs -> {
|
schemeManager.register(Reply.class, indexSpecs -> {
|
||||||
indexSpecs.add(new IndexSpec()
|
indexSpecs.add(new IndexSpec()
|
||||||
|
@ -337,6 +348,17 @@ public class SchemeInitializer implements ApplicationListener<ApplicationContext
|
||||||
var owner = reply.getSpec().getOwner();
|
var owner = reply.getSpec().getOwner();
|
||||||
return Comment.CommentOwner.ownerIdentity(owner.getKind(), owner.getName());
|
return Comment.CommentOwner.ownerIdentity(owner.getKind(), owner.getName());
|
||||||
})));
|
})));
|
||||||
|
indexSpecs.add(new IndexSpec()
|
||||||
|
.setName(Reply.REQUIRE_SYNC_ON_STARTUP_INDEX_NAME)
|
||||||
|
.setIndexFunc(simpleAttribute(Reply.class, reply -> {
|
||||||
|
var version = reply.getMetadata().getVersion();
|
||||||
|
var observedVersion = reply.getStatus().getObservedVersion();
|
||||||
|
if (observedVersion == null || observedVersion < version) {
|
||||||
|
return BooleanUtils.TRUE;
|
||||||
|
}
|
||||||
|
// do not care about the false case so return null to avoid indexing
|
||||||
|
return null;
|
||||||
|
})));
|
||||||
});
|
});
|
||||||
schemeManager.register(SinglePage.class);
|
schemeManager.register(SinglePage.class);
|
||||||
// storage.halo.run
|
// storage.halo.run
|
||||||
|
|
Loading…
Reference in New Issue