Skip to content

Commit

Permalink
fix: failed to load plugin when add fixedPluginPath dynamically in de…
Browse files Browse the repository at this point in the history
…velopment mode (halo-dev#2941)

#### What type of PR is this?
/kind bug
/area core

#### What this PR does / why we need it:
修复插件开发模式下后续增加的 fixedPluginPath 项无法被加载的问题
- 目前启动时会加载 pluginRepository 的所有 path,fixedPluginPath 被 DefaultDevelopmentPluginRepository 管理,所以在遍历 fixedPluginPath 加载时可能已经被加载过,需要判断是否被加载过,但即使被加载过也不能跳过而要继续执行创建/更新 plugin.yaml 资源的逻辑
- 创建/更新 plugin.yaml 时需要使用重试机制防止因为乐观锁冲突导致 Halo 无法启动

see halo-dev#2939 for more detail
#### Which issue(s) this PR fixes:

Fixes halo-dev#2939

#### Special notes for your reviewer:
/cc @halo-dev/sig-halo 
#### Does this PR introduce a user-facing change?

```release-note
修复插件开发模式下后续增加的 fixedPluginPath 项无法被加载的问题
```
  • Loading branch information
guqing authored Dec 14, 2022
1 parent df0e6cf commit 07f5b0d
Showing 1 changed file with 24 additions and 17 deletions.
41 changes: 24 additions & 17 deletions src/main/java/run/halo/app/plugin/PluginDevelopmentInitializer.java
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
package run.halo.app.plugin;

import java.nio.file.Path;
import java.time.Duration;
import lombok.extern.slf4j.Slf4j;
import org.pf4j.PluginWrapper;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.dao.OptimisticLockingFailureException;
import org.springframework.lang.NonNull;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Mono;
import reactor.util.retry.Retry;
import run.halo.app.core.extension.Plugin;
import run.halo.app.extension.ExtensionClient;
import run.halo.app.extension.ReactiveExtensionClient;

/**
* @author guqing
Expand All @@ -22,10 +26,10 @@ public class PluginDevelopmentInitializer implements ApplicationListener<Applica

private final PluginProperties pluginProperties;

private final ExtensionClient extensionClient;
private final ReactiveExtensionClient extensionClient;

public PluginDevelopmentInitializer(HaloPluginManager haloPluginManager,
PluginProperties pluginProperties, ExtensionClient extensionClient) {
PluginProperties pluginProperties, ReactiveExtensionClient extensionClient) {
this.haloPluginManager = haloPluginManager;
this.pluginProperties = pluginProperties;
this.extensionClient = extensionClient;
Expand All @@ -41,19 +45,18 @@ public void onApplicationEvent(@NonNull ApplicationReadyEvent event) {

private void createFixedPluginIfNecessary(HaloPluginManager pluginManager) {
for (Path path : pluginProperties.getFixedPluginPath()) {
// already loaded
if (idForPath(path) != null) {
continue;
}

// for issue #2901
String pluginId;
// Already loaded do not load again
String pluginId = idForPath(path);

try {
pluginId = pluginManager.loadPlugin(path);
} catch (Exception e) {
log.warn(e.getMessage(), e);
continue;
// for issue #2901
if (pluginId == null) {
try {
pluginId = pluginManager.loadPlugin(path);
} catch (Exception e) {
log.warn(e.getMessage(), e);
continue;
}
}

PluginWrapper pluginWrapper = pluginManager.getPlugin(pluginId);
Expand All @@ -62,10 +65,14 @@ private void createFixedPluginIfNecessary(HaloPluginManager pluginManager) {
}
Plugin plugin = new YamlPluginFinder().find(pluginWrapper.getPluginPath());
extensionClient.fetch(Plugin.class, plugin.getMetadata().getName())
.ifPresentOrElse(persistent -> {
.flatMap(persistent -> {
plugin.getMetadata().setVersion(persistent.getMetadata().getVersion());
extensionClient.update(plugin);
}, () -> extensionClient.create(plugin));
return extensionClient.update(plugin);
})
.switchIfEmpty(Mono.defer(() -> extensionClient.create(plugin)))
.retryWhen(Retry.backoff(10, Duration.ofMillis(100))
.filter(t -> t instanceof OptimisticLockingFailureException))
.block();
}
}

Expand Down

0 comments on commit 07f5b0d

Please sign in to comment.