fix: route for the tag is not registered when halo starts (#3322)

#### What type of PR is this?
/kind bug
/area core
/milestone 2.3.x

#### What this PR does / why we need it:
1. 去掉原 TagReconciler 的 requeue 逻辑,来临时解决大量 tag 时 reconciler 空转导致 cpu 下不来的问题,参考: https://github.com/halo-dev/halo/issues/3311
2. 增加 TagRouteReconciler 在启动时注册路由

#### Which issue(s) this PR fixes:
Fixes #3321

#### Special notes for your reviewer:
/cc @halo-dev/sig-halo 
#### Does this PR introduce a user-facing change?
```release-note
修复 #3316 引入的 tags 标签的路由没有注册的问题
```
pull/3320/head
guqing 2023-02-15 21:52:12 +08:00 committed by GitHub
parent dd161eec19
commit 3cde340b71
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 61 additions and 51 deletions

View File

@ -1,6 +1,5 @@
package run.halo.app.core.extension.reconciler;
import java.time.Duration;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
@ -34,20 +33,17 @@ public class TagReconciler implements Reconciler<Reconciler.Request> {
@Override
public Result reconcile(Request request) {
return client.fetch(Tag.class, request.name())
.map(tag -> {
client.fetch(Tag.class, request.name())
.ifPresent(tag -> {
if (isDeleted(tag)) {
cleanUpResourcesAndRemoveFinalizer(request.name());
return new Result(false, null);
return;
}
addFinalizerIfNecessary(tag);
this.reconcileStatusPermalink(request.name());
reconcileStatusPosts(request.name());
return new Result(true, Duration.ofMinutes(1));
})
.orElseGet(() -> new Result(false, null));
});
return new Result(false, null);
}
@Override
@ -90,22 +86,6 @@ public class TagReconciler implements Reconciler<Reconciler.Request> {
});
}
private void reconcileStatusPermalink(String tagName) {
client.fetch(Tag.class, tagName)
.ifPresent(tag -> {
Tag oldTag = JsonUtils.deepCopy(tag);
tagPermalinkPolicy.onPermalinkDelete(oldTag);
tag.getStatusOrDefault()
.setPermalink(tagPermalinkPolicy.permalink(tag));
tagPermalinkPolicy.onPermalinkAdd(tag);
if (!oldTag.equals(tag)) {
client.update(tag);
}
});
}
private void reconcileStatusPosts(String tagName) {
client.fetch(Tag.class, tagName).ifPresent(tag -> {
Tag oldTag = JsonUtils.deepCopy(tag);

View File

@ -0,0 +1,56 @@
package run.halo.app.core.extension.reconciler;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import run.halo.app.content.permalinks.TagPermalinkPolicy;
import run.halo.app.core.extension.content.Tag;
import run.halo.app.extension.ExtensionClient;
import run.halo.app.extension.controller.Controller;
import run.halo.app.extension.controller.ControllerBuilder;
import run.halo.app.extension.controller.Reconciler;
@Component
@RequiredArgsConstructor
public class TagRouteReconciler implements Reconciler<Reconciler.Request> {
private final ExtensionClient client;
private final TagPermalinkPolicy tagPermalinkPolicy;
@Override
public Result reconcile(Request request) {
client.fetch(Tag.class, request.name())
.ifPresent(tag -> {
if (tag.getMetadata().getDeletionTimestamp() != null) {
// TagReconciler already did it, so there is no need to remove permalink
return;
}
reconcilePermalinkRoute(request.name());
});
return new Result(false, null);
}
private void reconcilePermalinkRoute(String tagName) {
client.fetch(Tag.class, tagName)
.ifPresent(tag -> {
final String oldPermalink = tag.getStatusOrDefault().getPermalink();
tagPermalinkPolicy.onPermalinkDelete(tag);
String permalink = tagPermalinkPolicy.permalink(tag);
tag.getStatusOrDefault().setPermalink(permalink);
tagPermalinkPolicy.onPermalinkAdd(tag);
if (!StringUtils.equals(permalink, oldPermalink)) {
client.update(tag);
}
});
}
@Override
public Controller setupWith(ControllerBuilder builder) {
return builder
.extension(new Tag())
.build();
}
}

View File

@ -40,32 +40,6 @@ class TagReconcilerTest {
@InjectMocks
private TagReconciler tagReconciler;
@Test
void reconcile() {
Tag tag = tag();
when(client.fetch(eq(Tag.class), eq("fake-tag")))
.thenReturn(Optional.of(tag));
when(tagPermalinkPolicy.permalink(any()))
.thenAnswer(arg -> "/tags/" + tag.getSpec().getSlug());
ArgumentCaptor<Tag> captor = ArgumentCaptor.forClass(Tag.class);
tagReconciler.reconcile(new TagReconciler.Request("fake-tag"));
verify(client, times(3)).update(captor.capture());
verify(tagPermalinkPolicy, times(1)).onPermalinkAdd(any());
verify(tagPermalinkPolicy, times(1)).onPermalinkDelete(any());
Tag capture = captor.getValue();
assertThat(capture.getStatus().getPermalink()).isEqualTo("/tags/fake-slug");
// change slug
tag.getSpec().setSlug("new-slug");
tagReconciler.reconcile(new TagReconciler.Request("fake-tag"));
verify(client, times(4)).update(captor.capture());
verify(tagPermalinkPolicy, times(2)).onPermalinkAdd(any());
verify(tagPermalinkPolicy, times(2)).onPermalinkDelete(any());
assertThat(capture.getStatus().getPermalink()).isEqualTo("/tags/new-slug");
}
@Test
void reconcileDelete() {
Tag tag = tag();