mirror of https://github.com/halo-dev/halo
fix: plugin status check to prevent inconsistent status (#3235)
#### What type of PR is this? /kind improvement /area core /milestone 2.3.x #### What this PR does / why we need it: 当开发模式启动时上传 JAR 运行插件会出现插件不存在的异常,但由于 PluginReconciler 中检查状态不一致后 return 在 optional 语句中只是让当前 optional 后面的代码停止执行,还会继续执行 optional 外面的代码导致 status 的异常信息不一致,进而 object equals 始终为 false 而无法让 reconciler 终止运行导致循环。 此 PR 调整了一下代码位置,进入 reconciler 时先进行检查,如果不满足则不执行后面的代码同时将信息写入 plugin.status 让用户知晓。 此问题是修改了 Reconciler 判断逻辑后出现的 https://github.com/halo-dev/halo/pull/3210 ,因此不影响之前的代码只针对当前 2.3.x #### Special notes for your reviewer: how to test it? 1. 模拟一个插件找不到的错误场景例如以生产模式启动插件但配置 fixed-plugin 指定为插件项目目录 2. 启动 Halo 看 Reconciler 是否会一直在控制台输出日志 3. 卸载它能成功 /cc @halo-dev/sig-halo #### Does this PR introduce a user-facing change? ```release-note None ```pull/3236/head^2
parent
df9b04c4d5
commit
6809dbb251
|
@ -36,6 +36,7 @@ import run.halo.app.infra.utils.JsonUtils;
|
|||
import run.halo.app.infra.utils.PathUtils;
|
||||
import run.halo.app.plugin.HaloPluginManager;
|
||||
import run.halo.app.plugin.PluginConst;
|
||||
import run.halo.app.plugin.PluginNotFoundException;
|
||||
import run.halo.app.plugin.PluginStartingError;
|
||||
import run.halo.app.plugin.event.PluginCreatedEvent;
|
||||
import run.halo.app.plugin.resources.BundleResourceUtils;
|
||||
|
@ -82,24 +83,13 @@ public class PluginReconciler implements Reconciler<Request> {
|
|||
ensurePluginLoaded();
|
||||
}
|
||||
|
||||
if (!checkPluginState(name)) {
|
||||
return;
|
||||
}
|
||||
|
||||
client.fetch(Plugin.class, name).ifPresent(plugin -> {
|
||||
Plugin oldPlugin = JsonUtils.deepCopy(plugin);
|
||||
Plugin.PluginStatus pluginStatus = plugin.statusNonNull();
|
||||
PluginWrapper pluginWrapper = haloPluginManager.getPlugin(name);
|
||||
if (pluginWrapper == null) {
|
||||
pluginStatus.setPhase(PluginState.FAILED);
|
||||
pluginStatus.setReason("PluginNotFound");
|
||||
pluginStatus.setMessage("Plugin " + name + " not found in plugin manager");
|
||||
} else {
|
||||
// Set to the correct state
|
||||
pluginStatus.setPhase(pluginWrapper.getPluginState());
|
||||
|
||||
if (haloPluginManager.getUnresolvedPlugins().contains(pluginWrapper)) {
|
||||
// load and resolve plugin
|
||||
haloPluginManager.loadPlugin(pluginWrapper.getPluginPath());
|
||||
}
|
||||
}
|
||||
|
||||
String logo = plugin.getSpec().getLogo();
|
||||
if (PathUtils.isAbsoluteUri(logo)) {
|
||||
pluginStatus.setLogo(logo);
|
||||
|
@ -119,6 +109,36 @@ public class PluginReconciler implements Reconciler<Request> {
|
|||
stopPlugin(name);
|
||||
}
|
||||
|
||||
private boolean checkPluginState(String name) {
|
||||
// check plugin state
|
||||
return client.fetch(Plugin.class, name)
|
||||
.map(plugin -> {
|
||||
Plugin oldPlugin = JsonUtils.deepCopy(plugin);
|
||||
Plugin.PluginStatus pluginStatus = plugin.statusNonNull();
|
||||
PluginWrapper pluginWrapper = haloPluginManager.getPlugin(name);
|
||||
if (pluginWrapper == null) {
|
||||
pluginStatus.setPhase(PluginState.FAILED);
|
||||
pluginStatus.setReason("PluginNotFound");
|
||||
pluginStatus.setMessage(
|
||||
"Plugin " + plugin.getMetadata().getName()
|
||||
+ " not found in plugin manager.");
|
||||
if (!plugin.equals(oldPlugin)) {
|
||||
client.update(plugin);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
// Set to the correct state
|
||||
pluginStatus.setPhase(pluginWrapper.getPluginState());
|
||||
|
||||
if (haloPluginManager.getUnresolvedPlugins().contains(pluginWrapper)) {
|
||||
// load and resolve plugin
|
||||
haloPluginManager.loadPlugin(pluginWrapper.getPluginPath());
|
||||
}
|
||||
return true;
|
||||
})
|
||||
.orElse(false);
|
||||
}
|
||||
|
||||
private void ensurePluginLoaded() {
|
||||
// load plugin if exists in plugin root paths.
|
||||
List<PluginWrapper> loadedPlugins = haloPluginManager.getPlugins();
|
||||
|
@ -172,20 +192,15 @@ public class PluginReconciler implements Reconciler<Request> {
|
|||
|
||||
private boolean verifyStartCondition(String pluginName) {
|
||||
PluginWrapper pluginWrapper = haloPluginManager.getPlugin(pluginName);
|
||||
if (pluginWrapper == null) {
|
||||
throw new PluginNotFoundException(
|
||||
"Plugin " + pluginName + " not found in plugin manager.");
|
||||
}
|
||||
return client.fetch(Plugin.class, pluginName).map(plugin -> {
|
||||
Plugin.PluginStatus oldStatus = JsonUtils.deepCopy(plugin.statusNonNull());
|
||||
|
||||
Plugin.PluginStatus status = plugin.statusNonNull();
|
||||
status.setLastTransitionTime(Instant.now());
|
||||
if (pluginWrapper == null) {
|
||||
status.setPhase(PluginState.FAILED);
|
||||
status.setReason("PluginNotFound");
|
||||
status.setMessage("Plugin [" + pluginName + "] not found in plugin manager");
|
||||
if (!oldStatus.equals(status)) {
|
||||
client.update(plugin);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if this plugin version is match requires param.
|
||||
if (!haloPluginManager.validatePluginVersion(pluginWrapper)) {
|
||||
|
@ -206,6 +221,9 @@ public class PluginReconciler implements Reconciler<Request> {
|
|||
status.setPhase(pluginState);
|
||||
status.setReason("PluginDisabled");
|
||||
status.setMessage("The plugin is disabled for some reason and cannot be started.");
|
||||
if (!oldStatus.equals(status)) {
|
||||
client.update(plugin);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}).orElse(false);
|
||||
|
|
Loading…
Reference in New Issue