From d777dbf7edf5ebd20f2fc0eb023ff67401696c70 Mon Sep 17 00:00:00 2001 From: John Niang Date: Wed, 13 Dec 2023 14:40:10 +0800 Subject: [PATCH] Initialize schemes before refreshing application context (#5032) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #### What type of PR is this? /kind improvement /area core #### What this PR does / why we need it: Prior to this proposal, we encountered an error requesting any page before Halo is in ready state. That is because the timing of schemes initialization is incorrect. The current proposal is to advance schemes initialization before refreshing application and removes `SchemeInitializedEvent` because it cannot be listened by other beans. #### Which issue(s) this PR fixes: Fixes https://github.com/halo-dev/halo/issues/4946 #### Special notes for your reviewer: #### Does this PR introduce a user-facing change? ```release-note 修复 Halo 还未处于准备就绪时访问页面或接口出现“Scheme not found”错误的问题 ``` --- .../app/config/ExtensionConfiguration.java | 16 ++------- .../halo/app/content/PostIndexInformer.java | 14 ++------ .../ExtensionCompositeRouterFunction.java | 34 ++++++++++++++++--- .../app/infra/DefaultThemeInitializer.java | 5 +-- .../infra/ExtensionResourceInitializer.java | 16 +++++---- .../app/infra/SchemeInitializedEvent.java | 11 ------ .../run/halo/app/infra/SchemeInitializer.java | 29 +++++++--------- .../halo/app/search/IndicesInitializer.java | 15 +++----- .../router/ThemeCompositeRouterFunction.java | 14 +++++--- .../main/resources/META-INF/spring.factories | 1 + .../ExtensionCompositeRouterFunctionTest.java | 31 ++++++++++++----- .../ExtensionResourceInitializerTest.java | 9 ++--- 12 files changed, 98 insertions(+), 97 deletions(-) delete mode 100644 application/src/main/java/run/halo/app/infra/SchemeInitializedEvent.java create mode 100644 application/src/main/resources/META-INF/spring.factories diff --git a/application/src/main/java/run/halo/app/config/ExtensionConfiguration.java b/application/src/main/java/run/halo/app/config/ExtensionConfiguration.java index 5eb0c2e9e..b9133cd9c 100644 --- a/application/src/main/java/run/halo/app/config/ExtensionConfiguration.java +++ b/application/src/main/java/run/halo/app/config/ExtensionConfiguration.java @@ -5,8 +5,6 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.reactive.function.server.RouterFunction; import org.springframework.web.reactive.function.server.ServerResponse; -import run.halo.app.extension.DefaultSchemeManager; -import run.halo.app.extension.DefaultSchemeWatcherManager; import run.halo.app.extension.ExtensionClient; import run.halo.app.extension.ReactiveExtensionClient; import run.halo.app.extension.SchemeManager; @@ -19,18 +17,8 @@ public class ExtensionConfiguration { @Bean RouterFunction extensionsRouterFunction(ReactiveExtensionClient client, - SchemeWatcherManager watcherManager) { - return new ExtensionCompositeRouterFunction(client, watcherManager); - } - - @Bean - SchemeManager schemeManager(SchemeWatcherManager watcherManager) { - return new DefaultSchemeManager(watcherManager); - } - - @Bean - SchemeWatcherManager schemeWatcherManager() { - return new DefaultSchemeWatcherManager(); + SchemeWatcherManager watcherManager, SchemeManager schemeManager) { + return new ExtensionCompositeRouterFunction(client, watcherManager, schemeManager); } @Configuration(proxyBeanMethods = false) diff --git a/application/src/main/java/run/halo/app/content/PostIndexInformer.java b/application/src/main/java/run/halo/app/content/PostIndexInformer.java index 7d4f1f87f..0ede05bdf 100644 --- a/application/src/main/java/run/halo/app/content/PostIndexInformer.java +++ b/application/src/main/java/run/halo/app/content/PostIndexInformer.java @@ -7,6 +7,7 @@ import java.util.Set; import java.util.concurrent.locks.StampedLock; import java.util.function.BiConsumer; import org.springframework.beans.factory.DisposableBean; +import org.springframework.boot.context.event.ApplicationStartedEvent; import org.springframework.context.ApplicationListener; import org.springframework.lang.NonNull; import org.springframework.stereotype.Component; @@ -19,7 +20,6 @@ import run.halo.app.extension.MetadataUtil; import run.halo.app.extension.Unstructured; import run.halo.app.extension.Watcher; import run.halo.app.extension.controller.RequestSynchronizer; -import run.halo.app.infra.SchemeInitializedEvent; /** *

Monitor changes to {@link Post} resources and establish a local, in-memory cache in an @@ -33,7 +33,7 @@ import run.halo.app.infra.SchemeInitializedEvent; * @since 2.0.0 */ @Component -public class PostIndexInformer implements ApplicationListener, +public class PostIndexInformer implements ApplicationListener, DisposableBean { public static final String TAG_POST_INDEXER = "tag-post-indexer"; public static final String LABEL_INDEXER_NAME = "post-label-indexer"; @@ -71,10 +71,6 @@ public class PostIndexInformer implements ApplicationListener getByIndex(String indexName, String indexKey) { - return postIndexer.getByIndex(indexName, indexKey); - } - public Set getByTagName(String tagName) { return postIndexer.getByIndex(TAG_POST_INDEXER, tagName); } @@ -104,10 +100,6 @@ public class PostIndexInformer implements ApplicationListener { public static final Set REQUIRED_EXTENSION_LOCATIONS = Set.of("classpath:/extensions/*.yaml", "classpath:/extensions/*.yml"); @@ -45,8 +47,7 @@ public class ExtensionResourceInitializer { this.eventPublisher = eventPublisher; } - @EventListener(SchemeInitializedEvent.class) - public Mono initialize(SchemeInitializedEvent initializedEvent) { + public void onApplicationEvent(ApplicationStartedEvent initializedEvent) { var locations = new HashSet(); if (!haloProperties.isRequiredExtensionDisabled()) { locations.addAll(REQUIRED_EXTENSION_LOCATIONS); @@ -55,10 +56,10 @@ public class ExtensionResourceInitializer { locations.addAll(haloProperties.getInitialExtensionLocations()); } if (CollectionUtils.isEmpty(locations)) { - return Mono.empty(); + return; } - return Flux.fromIterable(locations) + Flux.fromIterable(locations) .doOnNext(location -> log.debug("Trying to initialize extension resources from location: {}", location)) .map(this::listResources) @@ -82,7 +83,8 @@ public class ExtensionResourceInitializer { } }) .then(Mono.fromRunnable( - () -> eventPublisher.publishEvent(new ExtensionInitializedEvent(this)))); + () -> eventPublisher.publishEvent(new ExtensionInitializedEvent(this)))) + .block(Duration.ofMinutes(1)); } private Mono createOrUpdate(Unstructured extension) { diff --git a/application/src/main/java/run/halo/app/infra/SchemeInitializedEvent.java b/application/src/main/java/run/halo/app/infra/SchemeInitializedEvent.java deleted file mode 100644 index 647aa518c..000000000 --- a/application/src/main/java/run/halo/app/infra/SchemeInitializedEvent.java +++ /dev/null @@ -1,11 +0,0 @@ -package run.halo.app.infra; - -import org.springframework.context.ApplicationEvent; - -public class SchemeInitializedEvent extends ApplicationEvent { - - public SchemeInitializedEvent(Object source) { - super(source); - } - -} diff --git a/application/src/main/java/run/halo/app/infra/SchemeInitializer.java b/application/src/main/java/run/halo/app/infra/SchemeInitializer.java index ff2bb8b82..e7e9bb7d3 100644 --- a/application/src/main/java/run/halo/app/infra/SchemeInitializer.java +++ b/application/src/main/java/run/halo/app/infra/SchemeInitializer.java @@ -1,7 +1,6 @@ package run.halo.app.infra; -import org.springframework.boot.context.event.ApplicationStartedEvent; -import org.springframework.context.ApplicationEventPublisher; +import org.springframework.boot.context.event.ApplicationContextInitializedEvent; import org.springframework.context.ApplicationListener; import org.springframework.lang.NonNull; import org.springframework.stereotype.Component; @@ -36,7 +35,8 @@ import run.halo.app.core.extension.notification.Reason; import run.halo.app.core.extension.notification.ReasonType; import run.halo.app.core.extension.notification.Subscription; import run.halo.app.extension.ConfigMap; -import run.halo.app.extension.SchemeManager; +import run.halo.app.extension.DefaultSchemeManager; +import run.halo.app.extension.DefaultSchemeWatcherManager; import run.halo.app.extension.Secret; import run.halo.app.migration.Backup; import run.halo.app.plugin.extensionpoint.ExtensionDefinition; @@ -45,20 +45,17 @@ import run.halo.app.search.extension.SearchEngine; import run.halo.app.security.PersonalAccessToken; @Component -public class SchemeInitializer implements ApplicationListener { - - private final SchemeManager schemeManager; - - private final ApplicationEventPublisher eventPublisher; - - public SchemeInitializer(SchemeManager schemeManager, - ApplicationEventPublisher eventPublisher) { - this.schemeManager = schemeManager; - this.eventPublisher = eventPublisher; - } +public class SchemeInitializer implements ApplicationListener { @Override - public void onApplicationEvent(@NonNull ApplicationStartedEvent event) { + public void onApplicationEvent(@NonNull ApplicationContextInitializedEvent event) { + var watcherManager = new DefaultSchemeWatcherManager(); + var schemeManager = new DefaultSchemeManager(watcherManager); + + var beanFactory = event.getApplicationContext().getBeanFactory(); + beanFactory.registerSingleton("schemeWatcherManager", watcherManager); + beanFactory.registerSingleton("schemeManager", schemeManager); + schemeManager.register(Role.class); // plugin.halo.run @@ -108,7 +105,5 @@ public class SchemeInitializer implements ApplicationListener latch.countDown()) - .subscribe(); - latch.await(); - watch.stop(); + indicesService.rebuildPostIndices().block(Duration.ofMinutes(5)); log.info("Initialized post indices. Usage: {}", watch); } diff --git a/application/src/main/java/run/halo/app/theme/router/ThemeCompositeRouterFunction.java b/application/src/main/java/run/halo/app/theme/router/ThemeCompositeRouterFunction.java index 996ee0c41..f1b39af50 100644 --- a/application/src/main/java/run/halo/app/theme/router/ThemeCompositeRouterFunction.java +++ b/application/src/main/java/run/halo/app/theme/router/ThemeCompositeRouterFunction.java @@ -4,7 +4,7 @@ import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; import lombok.RequiredArgsConstructor; -import org.springframework.context.ApplicationEvent; +import org.springframework.boot.context.event.ApplicationStartedEvent; import org.springframework.context.event.EventListener; import org.springframework.lang.NonNull; import org.springframework.stereotype.Component; @@ -15,7 +15,6 @@ import org.springframework.web.reactive.function.server.ServerRequest; import org.springframework.web.reactive.function.server.ServerResponse; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; -import run.halo.app.infra.SchemeInitializedEvent; import run.halo.app.infra.SystemConfigurableEnvironmentFetcher; import run.halo.app.infra.SystemSetting; import run.halo.app.theme.DefaultTemplateEnum; @@ -90,10 +89,15 @@ public class ThemeCompositeRouterFunction implements RouterFunction