bash_go_service/backend-service/pkg/service/version.go

146 lines
3.9 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package service
import (
"bash_go_service/shared/pkg/constants"
"bash_go_service/shared/pkg/logger"
"bash_go_service/version/pkg/handler"
"context"
"os"
"path/filepath"
"time"
"github.com/spf13/viper"
)
// VersionCheckTask represents a task that checks for version updates.
type VersionCheckTask struct {
interval time.Duration
}
// NewVersionCheckTask creates a new VersionCheckTask.
func NewVersionCheckTask() *VersionCheckTask {
interval := viper.GetDuration("update_checker.interval")
if interval < 1*time.Hour {
interval = 1 * time.Hour // 默认值为1小时
}
logger.Debug("VersionCheckTask interval: %v", interval)
return &VersionCheckTask{
interval: interval,
}
}
// Execute runs the version check task periodically.
func (t *VersionCheckTask) Execute(ctx context.Context) {
ticker := time.NewTicker(t.interval)
defer ticker.Stop()
for {
select {
case <-ticker.C:
t.CheckUpdate(ctx)
case <-ctx.Done():
logger.Info("VersionCheckTask stopped")
return
}
}
}
// 检查更新,将文件下载到本地,在下次启动程序时执行更新
func (t *VersionCheckTask) CheckUpdate(ctx context.Context) {
logger.Info("Executing version update check at %v", time.Now())
res, err := handler.CheckVersionUpdate()
needUpdate, newVersion, md5sum, soMd5 := res.NeedUpdate, res.Version, res.ExeMd5, res.SoMd5
if err != nil {
logger.Error("Failed to check for updates: %v", err)
return
}
if !needUpdate {
logger.Info("No update needed.")
return
}
currentExePath, err := os.Executable()
if err != nil {
logger.Error("Failed to get executable path: %v", err)
return
}
currentExeDir := filepath.Dir(currentExePath)
currentExeBase := filepath.Base(currentExePath)
backupPath, err := handler.BackupCurrentExecutable(currentExePath, currentExeBase, currentExeDir)
if err != nil {
logger.Error("Failed to backup current executable: %v", err)
return
}
logger.Info("Backup current executable to: %s", backupPath)
currentSoPath := filepath.Join(constants.SoPath, constants.SoName)
soBackupPath, err := handler.BackupCurrentExecutable(
currentSoPath,
constants.SoName, currentExeDir)
if err != nil {
logger.Error("Failed to backup so-lib: %v", err)
return
}
logger.Info("Backup current so-lib to: %s", soBackupPath)
// 下载最新的exe并且校验md5
newExePath, err := handler.DownloadNewExecutable(constants.SoPath, currentExeBase, newVersion, "exe")
if err != nil {
logger.Error("Failed to download new executable: %v", err)
_ = os.Remove(backupPath)
return
}
if err := handler.VerifyMD5(newExePath, md5sum); err != nil {
logger.Error("MD5 verification failed: %v", err)
// Attempt rollback
_ = os.Remove(newExePath)
return
}
// 下载最新的so并且校验md5
newSoPath, err := handler.DownloadNewExecutable(constants.SoPath, constants.SoName, newVersion, "so")
if err != nil {
logger.Error("Failed to download new so-lib: %v", err)
// Attempt rollback
_ = os.Remove(soBackupPath)
return
}
if err := handler.VerifyMD5(newSoPath, soMd5); err != nil {
logger.Error("MD5 verification failed: %v", err)
// Attempt rollback
_ = os.Remove(newSoPath)
return
}
info := handler.CreateUpdateInfo(backupPath, newExePath, currentExePath, soBackupPath, newSoPath, currentSoPath)
err = handler.SaveUpdateInfo(currentExePath, *info)
if err != nil {
logger.Error("Failed to save update info: %v", err)
return
}
logger.Info("The update will be initiated on the next application start.")
// 下次启动的时候检查更新
// if err := handler.ExecuteUpdate(currentExeDir, backupPath, newExePath, currentExePath); err != nil {
// logger.Error("Failed to execute update: %v", err)
// // Attempt rollback
// _ = os.Rename(backupPath, currentExePath)
// _ = os.Remove(newExePath)
// return
// }
// logger.Info("Update process initiated, current process exiting.")
//
}
// Name returns the name of the task.
func (t *VersionCheckTask) Name() string {
return "VersionCheckTask"
}