Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support restarting Halo #4361

Merged
merged 5 commits into from Aug 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 0 additions & 2 deletions application/build.gradle
Expand Up @@ -52,8 +52,6 @@ dependencies {
annotationProcessor "org.springframework.boot:spring-boot-configuration-processor"
annotationProcessor "org.springframework:spring-context-indexer"

developmentOnly 'org.springframework.boot:spring-boot-devtools'

testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.springframework.security:spring-security-test'
testImplementation 'io.projectreactor:reactor-test'
Expand Down
@@ -0,0 +1,77 @@
package run.halo.app.actuator;

import java.io.Closeable;
import java.io.IOException;
import java.util.Collections;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.actuate.endpoint.annotation.WriteOperation;
import org.springframework.boot.actuate.endpoint.web.annotation.WebEndpoint;
import org.springframework.boot.context.event.ApplicationStartedEvent;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationListener;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.stereotype.Component;
import run.halo.app.Application;

@WebEndpoint(id = "restart")
@Component
@Slf4j
public class RestartEndpoint implements ApplicationListener<ApplicationStartedEvent> {

private SpringApplication application;

private String[] args;

private ConfigurableApplicationContext context;

@WriteOperation
public Object restart() {
var threadGroup = new ThreadGroup("RestartGroup");
var thread = new Thread(threadGroup, this::doRestart, "restartMain");
thread.setDaemon(false);
thread.setContextClassLoader(Application.class.getClassLoader());
thread.start();
return Collections.singletonMap("message", "Restarting");
}

private synchronized void doRestart() {
log.info("Restarting...");
if (this.context != null) {
try {
closeRecursively(this.context);
var shutdownHandlers = SpringApplication.getShutdownHandlers();
if (shutdownHandlers instanceof Runnable runnable) {
// clear closedContext in org.springframework.boot.SpringApplicationShutdownHook
runnable.run();
}
this.context = this.application.run(args);
log.info("Restarted");
} catch (Throwable t) {
log.error("Failed to restart.", t);
}
}
}

private static void closeRecursively(ApplicationContext ctx) {
while (ctx != null) {
if (ctx instanceof Closeable closeable) {
try {
closeable.close();
} catch (IOException e) {
log.error("Cannot close context: {}", ctx.getId(), e);
}
}
ctx = ctx.getParent();
}
}

@Override
public void onApplicationEvent(ApplicationStartedEvent event) {
if (this.context == null) {
this.application = event.getSpringApplication();
this.args = event.getArgs();
this.context = event.getApplicationContext();
}
}
}
2 changes: 1 addition & 1 deletion application/src/main/resources/application.yaml
Expand Up @@ -64,7 +64,7 @@ management:
endpoints:
web:
exposure:
include: ["health", "info", "startup", "globalinfo", "logfile", "shutdown"]
include: ["health", "info", "startup", "globalinfo", "logfile", "shutdown", "restart"]
endpoint:
shutdown:
enabled: true
Expand Down
8 changes: 4 additions & 4 deletions console/src/locales/en.yaml
Expand Up @@ -1003,9 +1003,9 @@ core:
description: Are you sure you want to delete the backup?
restore:
title: Restore successfully
description: After successful restore, you need to restart Halo to load the system resources normally. After clicking OK, we will automatically stop running Halo.
shutdown:
toast_success: Requested to shutdown operation
description: After successful restore, you need to restart Halo to load the system resources normally. After clicking OK, we will automatically restart Halo.
restart:
toast_success: Requested to restart
list:
phases:
pending: Pending
Expand All @@ -1018,7 +1018,7 @@ core:
tips:
first: 1. The restore process may last for a long time, please do not refresh the page during this period.
second: 2. During the restore process, although the existing data will not be cleaned up, if there is a conflict, the data will be overwritten.
third: 3. After the restore is completed, you will be prompted to stop running Halo, and you may need to run it manually after stopping.
third: 3. After the restore is completed, you need to restart Halo to load the system resources normally.
complete: Restore completed, waiting for restart...
start: Start restore
exception:
Expand Down
8 changes: 4 additions & 4 deletions console/src/locales/zh-CN.yaml
Expand Up @@ -1003,9 +1003,9 @@ core:
description: 确定要删除该备份吗?
restore:
title: 恢复成功
description: 恢复成功之后,需要重启一下 Halo 才能够正常加载系统资源,点击确定之后我们会自动停止运行 Halo
shutdown:
toast_success: 已请求停止运行
description: 恢复成功之后,需要重启一下 Halo 才能够正常加载系统资源,点击确定之后我们会自动重启 Halo
restart:
toast_success: 已请求重启
list:
phases:
pending: 准备中
Expand All @@ -1018,7 +1018,7 @@ core:
tips:
first: 1. 恢复过程可能会持续较长时间,期间请勿刷新页面。
second: 2. 在恢复的过程中,虽然已有的数据不会被清理掉,但如果有冲突的数据将被覆盖。
third: 3. 恢复完成之后会提示停止运行 Halo,停止之后可能需要手动运行
third: 3. 恢复完成之后需要重启 Halo 才能够正常加载系统资源
complete: 恢复完成,等待重启...
start: 开始恢复
exception:
Expand Down
8 changes: 4 additions & 4 deletions console/src/locales/zh-TW.yaml
Expand Up @@ -1003,9 +1003,9 @@ core:
description: 確定要刪除此備份嗎?
restore:
title: 還原成功
description: 還原成功後,需要重新啟動 Halo 才能正常載入系統資源,點擊確定後我們會自動停止運行 Halo。
shutdown:
toast_success: 已請求停止運行
description: 還原成功後,需要重新啟動 Halo 才能正常載入系統資源,點擊確定之後,我們會自動重啟 Halo。
restart:
toast_success: 已請求重啟
list:
phases:
pending: 準備中
Expand All @@ -1018,7 +1018,7 @@ core:
tips:
first: 1. 還原過程可能需要較長時間,期間請勿重新整理頁面。
second: 2. 在還原過程中,雖然已有的資料不會被清除,但若有衝突的資料將被覆蓋。
third: 3. 還原完成後會提示停止運行 Halo,停止後可能需要手動啟動
third: 3. 還原完成後需要重新啟動 Halo 才能正常載入系統資源
complete: 恢復完成,等待重啟...
start: 開始還原
exception:
Expand Down
4 changes: 2 additions & 2 deletions console/src/modules/system/backup/tabs/Restore.vue
Expand Up @@ -25,8 +25,8 @@ const onUploaded = () => {
};

async function handleShutdown() {
await axios.post(`/actuator/shutdown`);
Toast.success(t("core.backup.operations.shutdown.toast_success"));
await axios.post(`/actuator/restart`);
Toast.success(t("core.backup.operations.restart.toast_success"));

setTimeout(() => {
complete.value = true;
Expand Down