refactor: add list options for sync all synchronizer (#6145)

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

#### What this PR does / why we need it:
为启动时同步添加 ListOptions 选项为后续保持 ExtensionMatcher 的纯粹做准备,后续将移除 ExtensionMatcher 中多余的方法声明,只保留 match 方法,最终的结果希望是
```java
@FunctionalInterface
public interface ExtensionMatcher {
    boolean match(Extension extension);
}
```
以前构建 Controller 的写法
```java
public Controller setupWith(ControllerBuilder builder) {
         return builder
            .extension(new Post())
            .onAddMatcher(DefaultExtensionMatcher.builder(client, Post.GVK)
                .fieldSelector(FieldSelector.of(
                    equal(Post.REQUIRE_SYNC_ON_STARTUP_INDEX_NAME, TRUE))
                )
                .build()
            )
           .build();
}
```
现在的写法
```java
public Controller setupWith(ControllerBuilder builder) {
        var post = new Post();
        return builder
            .extension(post)
            // 当有新数据添加时
            .onAddMatcher(extension -> "fake-post".equals(extension.getMetadata().getName()))
            // 使用 syncAllListOptions 作为启动时同步的查询条件过滤不需要的数据
            .syncAllListOptions(ListOptions.builder()
                .fieldQuery(equal(Post.REQUIRE_SYNC_ON_STARTUP_INDEX_NAME, TRUE))
                .build()
            )
            .build();
    }
```

#### Does this PR introduce a user-facing change?
```release-note
开发者相关:重构 ControllerBuilder 的匹配条件并增加 syncAllListOptions 作为启动时同步的查询条件
```
pull/6131/head
guqing 2024-06-26 14:50:50 +08:00 committed by GitHub
parent 50f751dda2
commit 3f94cfc9a8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 74 additions and 22 deletions

View File

@ -4,11 +4,20 @@ import run.halo.app.extension.router.selector.FieldSelector;
import run.halo.app.extension.router.selector.LabelSelector;
public interface ExtensionMatcher {
GroupVersionKind getGvk();
@Deprecated(since = "2.17.0", forRemoval = true)
default GroupVersionKind getGvk() {
return null;
}
LabelSelector getLabelSelector();
@Deprecated(since = "2.17.0", forRemoval = true)
default LabelSelector getLabelSelector() {
return null;
}
FieldSelector getFieldSelector();
@Deprecated(since = "2.17.0", forRemoval = true)
default FieldSelector getFieldSelector() {
return null;
}
boolean match(Extension extension);
}

View File

@ -4,6 +4,8 @@ import java.util.Objects;
import lombok.Builder;
import lombok.Getter;
import org.springframework.util.Assert;
import run.halo.app.extension.router.selector.FieldSelector;
import run.halo.app.extension.router.selector.LabelSelector;
public class WatcherExtensionMatchers {
@Getter
@ -38,15 +40,15 @@ public class WatcherExtensionMatchers {
}
public ExtensionMatcher onAddMatcher() {
return this.onAddMatcher;
return delegateExtensionMatcher(this.onAddMatcher);
}
public ExtensionMatcher onUpdateMatcher() {
return this.onUpdateMatcher;
return delegateExtensionMatcher(this.onUpdateMatcher);
}
public ExtensionMatcher onDeleteMatcher() {
return this.onDeleteMatcher;
return delegateExtensionMatcher(this.onDeleteMatcher);
}
public static WatcherExtensionMatchersBuilder builder(ExtensionClient client,
@ -58,4 +60,32 @@ public class WatcherExtensionMatchers {
GroupVersionKind gvk) {
return DefaultExtensionMatcher.builder(client, gvk).build();
}
/**
* Remove this method when the deprecated methods are removed.
*/
ExtensionMatcher delegateExtensionMatcher(ExtensionMatcher matcher) {
return new ExtensionMatcher() {
@Override
public GroupVersionKind getGvk() {
return matcher.getGvk();
}
@Override
public LabelSelector getLabelSelector() {
return matcher.getLabelSelector();
}
@Override
public FieldSelector getFieldSelector() {
return matcher.getFieldSelector();
}
@Override
public boolean match(Extension extension) {
return extension.groupVersionKind().equals(gvk) && matcher.match(extension);
}
};
}
}

View File

@ -7,6 +7,7 @@ import org.springframework.util.Assert;
import run.halo.app.extension.Extension;
import run.halo.app.extension.ExtensionClient;
import run.halo.app.extension.ExtensionMatcher;
import run.halo.app.extension.ListOptions;
import run.halo.app.extension.WatcherExtensionMatchers;
import run.halo.app.extension.controller.Reconciler.Request;
@ -30,6 +31,8 @@ public class ControllerBuilder {
private ExtensionMatcher onUpdateMatcher;
private ListOptions syncAllListOptions;
private final ExtensionClient client;
private boolean syncAllOnStart = true;
@ -84,6 +87,11 @@ public class ControllerBuilder {
return this;
}
public ControllerBuilder syncAllListOptions(ListOptions syncAllListOptions) {
this.syncAllListOptions = syncAllListOptions;
return this;
}
public ControllerBuilder workerCount(int workerCount) {
this.workerCount = workerCount;
return this;
@ -116,8 +124,23 @@ public class ControllerBuilder {
client,
extension,
watcher,
extensionMatchers.onAddMatcher());
determineSyncAllListOptions());
return new DefaultController<>(name, reconciler, queue, synchronizer, minDelay, maxDelay,
workerCount);
}
ListOptions determineSyncAllListOptions() {
if (syncAllListOptions != null) {
return syncAllListOptions;
}
// In order to be compatible with the previous version of the code
// The previous version of the code determined syncAllListOptions through onAddMatcher
// TODO Will be removed later
if (onAddMatcher != null) {
return new ListOptions()
.setLabelSelector(onAddMatcher.getLabelSelector())
.setFieldSelector(onAddMatcher.getFieldSelector());
}
return new ListOptions();
}
}

View File

@ -5,7 +5,6 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Sort;
import run.halo.app.extension.Extension;
import run.halo.app.extension.ExtensionClient;
import run.halo.app.extension.ExtensionMatcher;
import run.halo.app.extension.GroupVersionKind;
import run.halo.app.extension.ListOptions;
import run.halo.app.extension.Watcher;
@ -27,7 +26,7 @@ public class RequestSynchronizer implements Synchronizer<Request> {
private final Watcher watcher;
private final ExtensionMatcher listMatcher;
private final ListOptions listOptions;
@Getter
private volatile boolean started = false;
@ -36,13 +35,13 @@ public class RequestSynchronizer implements Synchronizer<Request> {
ExtensionClient client,
Extension extension,
Watcher watcher,
ExtensionMatcher listMatcher) {
ListOptions listOptions) {
this.syncAllOnStart = syncAllOnStart;
this.client = client;
this.type = extension.groupVersionKind();
this.watcher = watcher;
this.indexedQueryEngine = client.indexedQueryEngine();
this.listMatcher = listMatcher;
this.listOptions = listOptions;
}
@Override
@ -54,11 +53,6 @@ public class RequestSynchronizer implements Synchronizer<Request> {
started = true;
if (syncAllOnStart) {
var listOptions = new ListOptions();
if (listMatcher != null) {
listOptions.setFieldSelector(listMatcher.getFieldSelector());
listOptions.setLabelSelector(listMatcher.getLabelSelector());
}
indexedQueryEngine.retrieveAll(type, listOptions, Sort.by("metadata.creationTimestamp"))
.forEach(name -> watcher.onAdd(new Request(name)));
}

View File

@ -18,7 +18,6 @@ import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.data.domain.Sort;
import run.halo.app.extension.ExtensionClient;
import run.halo.app.extension.ExtensionMatcher;
import run.halo.app.extension.FakeExtension;
import run.halo.app.extension.GroupVersionKind;
import run.halo.app.extension.ListOptions;
@ -37,16 +36,13 @@ class RequestSynchronizerTest {
@Mock
Watcher watcher;
@Mock
ExtensionMatcher listMatcher;
RequestSynchronizer synchronizer;
@BeforeEach
void setUp() {
when(client.indexedQueryEngine()).thenReturn(indexedQueryEngine);
synchronizer =
new RequestSynchronizer(true, client, new FakeExtension(), watcher, listMatcher);
new RequestSynchronizer(true, client, new FakeExtension(), watcher, new ListOptions());
assertFalse(synchronizer.isDisposed());
assertFalse(synchronizer.isStarted());
}
@ -71,7 +67,7 @@ class RequestSynchronizerTest {
@Test
void shouldStartCorrectlyWhenNotSyncingAllOnStart() {
synchronizer =
new RequestSynchronizer(false, client, new FakeExtension(), watcher, listMatcher);
new RequestSynchronizer(false, client, new FakeExtension(), watcher, new ListOptions());
assertFalse(synchronizer.isDisposed());
assertFalse(synchronizer.isStarted());