refactor: use nginx -s reload instead of systemd
- doc: add comment
This commit is contained in:
@@ -16,6 +16,8 @@ import (
|
||||
"yms-daemon/internal/transaction"
|
||||
)
|
||||
|
||||
// installJarOperation “安装后端 JAR 到发布存储”的事务操作,实现 transaction.Operation。
|
||||
// 它把源文件按给定身份提交到发布存储,并通过 Inspect 判断是否已生效。
|
||||
type installJarOperation struct {
|
||||
store *filestore.Store
|
||||
sourcePath string
|
||||
@@ -23,6 +25,8 @@ type installJarOperation struct {
|
||||
identity filestore.Identity
|
||||
}
|
||||
|
||||
// Apply 执行安装:打开源 JAR 并以指定身份提交到发布存储。
|
||||
// 参数 ctx 未使用,仅用于满足接口签名。返回值是打开或提交失败时的错误。
|
||||
func (o *installJarOperation) Apply(context.Context) error {
|
||||
source, err := os.Open(o.sourcePath)
|
||||
if err != nil {
|
||||
@@ -33,6 +37,9 @@ func (o *installJarOperation) Apply(context.Context) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// Inspect 检查安装是否已生效,返回事务检查结果。
|
||||
// 参数 ctx 未使用,仅用于满足接口签名。目标冲突时返回未知状态,未找到时返回未应用,
|
||||
// 找到时返回已应用并携带结果 JSON;其余情况返回错误。
|
||||
func (o *installJarOperation) Inspect(context.Context) (transaction.Inspection, error) {
|
||||
file, found, err := o.store.Inspect(o.releasePath, o.identity)
|
||||
if errors.Is(err, filestore.ErrDestinationConflict) {
|
||||
@@ -47,12 +54,16 @@ func (o *installJarOperation) Inspect(context.Context) (transaction.Inspection,
|
||||
return transaction.Inspection{Status: transaction.InspectionApplied, Result: resultJSON(file)}, nil
|
||||
}
|
||||
|
||||
// slotLinkOperation “替换槽位软链接”的事务操作,实现 transaction.Operation。
|
||||
// 它把槽位软链接原子地替换为期望目标,并在 desiredTarget 为空时移除软链接。
|
||||
type slotLinkOperation struct {
|
||||
path string
|
||||
desiredTarget string
|
||||
previousTarget string
|
||||
}
|
||||
|
||||
// Apply 原子地替换槽位软链接指向 desiredTarget,空目标则移除软链接。
|
||||
// ctx 用于 Inspect 调用。返回值是检查、目录校验或文件操作失败时的错误。
|
||||
func (o *slotLinkOperation) Apply(ctx context.Context) error {
|
||||
inspection, err := o.Inspect(ctx)
|
||||
if err != nil {
|
||||
@@ -118,6 +129,9 @@ func (o *slotLinkOperation) Apply(ctx context.Context) error {
|
||||
return syncDirectory(parent)
|
||||
}
|
||||
|
||||
// Inspect 判断槽位软链接当前状态与期望是否一致,返回事务检查结果。
|
||||
// 参数 ctx 未使用,仅用于满足接口签名。软链接指向 desiredTarget 时为已应用,
|
||||
// 指向 previousTarget 时为未应用,其余情况为未知;错误时返回错误。
|
||||
func (o *slotLinkOperation) Inspect(context.Context) (transaction.Inspection, error) {
|
||||
info, err := os.Lstat(o.path)
|
||||
if errors.Is(err, os.ErrNotExist) {
|
||||
@@ -155,15 +169,21 @@ func (o *slotLinkOperation) Inspect(context.Context) (transaction.Inspection, er
|
||||
return transaction.Inspection{Status: transaction.InspectionUnknown, Result: result}, nil
|
||||
}
|
||||
|
||||
// unitStartOperation “启动 systemd 单元”的事务操作,实现 transaction.Operation。
|
||||
// 它启动指定单元,并通过 Inspect 依据单元活跃状态判断是否已生效。
|
||||
type unitStartOperation struct {
|
||||
units systemd.Manager
|
||||
name string
|
||||
}
|
||||
|
||||
// Apply 启动指定单元。
|
||||
// ctx 用于取消。返回值是启动失败时的错误。
|
||||
func (o *unitStartOperation) Apply(ctx context.Context) error {
|
||||
return o.units.Start(ctx, o.name)
|
||||
}
|
||||
|
||||
// Inspect 检查单元是否已启动:活跃为已应用,非活跃或失败为未应用,其余为未知。
|
||||
// ctx 用于取消。返回值是事务检查结果;检查单元失败时返回错误。
|
||||
func (o *unitStartOperation) Inspect(ctx context.Context) (transaction.Inspection, error) {
|
||||
unit, err := o.units.Inspect(ctx, o.name)
|
||||
if err != nil {
|
||||
@@ -180,15 +200,21 @@ func (o *unitStartOperation) Inspect(ctx context.Context) (transaction.Inspectio
|
||||
}
|
||||
}
|
||||
|
||||
// unitStopOperation “停止 systemd 单元”的事务操作,实现 transaction.Operation。
|
||||
// 它停止指定单元,并通过 Inspect 依据单元活跃状态判断是否已停止。
|
||||
type unitStopOperation struct {
|
||||
units systemd.Manager
|
||||
name string
|
||||
}
|
||||
|
||||
// Apply 停止指定单元。
|
||||
// ctx 用于取消。返回值是停止失败时的错误。
|
||||
func (o *unitStopOperation) Apply(ctx context.Context) error {
|
||||
return o.units.Stop(ctx, o.name)
|
||||
}
|
||||
|
||||
// Inspect 检查单元是否已停止:非活跃或失败为已应用,活跃为未应用,其余为未知。
|
||||
// ctx 用于取消。返回值是事务检查结果;检查单元失败时返回错误。
|
||||
func (o *unitStopOperation) Inspect(ctx context.Context) (transaction.Inspection, error) {
|
||||
unit, err := o.units.Inspect(ctx, o.name)
|
||||
if err != nil {
|
||||
@@ -205,6 +231,8 @@ func (o *unitStopOperation) Inspect(ctx context.Context) (transaction.Inspection
|
||||
}
|
||||
}
|
||||
|
||||
// healthOperation “等待后端 Actuator 健康检查”的事务操作,实现 transaction.Operation。
|
||||
// 它等待健康检查就绪,并通过互斥锁缓存已确认的报告以避免重复探测。
|
||||
type healthOperation struct {
|
||||
units systemd.Manager
|
||||
checker actuatorChecker
|
||||
@@ -217,6 +245,8 @@ type healthOperation struct {
|
||||
confirmed bool
|
||||
}
|
||||
|
||||
// Apply 阻塞等待健康检查就绪,成功后缓存已确认的报告。
|
||||
// ctx 用于取消与超时。返回值是等待失败时的错误。
|
||||
func (o *healthOperation) Apply(ctx context.Context) error {
|
||||
report, err := o.checker.Wait(ctx, o.endpoint, o.timeout, o.running)
|
||||
if err != nil {
|
||||
@@ -229,6 +259,8 @@ func (o *healthOperation) Apply(ctx context.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Inspect 检查健康状态:若已有确认报告则直接返回,否则执行一次即时健康检查。
|
||||
// ctx 用于取消。返回值是事务检查结果;检查器错误由 healthInspection 归一化后返回。
|
||||
func (o *healthOperation) Inspect(ctx context.Context) (transaction.Inspection, error) {
|
||||
o.mu.Lock()
|
||||
if o.confirmed {
|
||||
@@ -241,6 +273,8 @@ func (o *healthOperation) Inspect(ctx context.Context) (transaction.Inspection,
|
||||
return healthInspection(report, ready, err)
|
||||
}
|
||||
|
||||
// running 判断后端单元当前是否处于活跃状态,作为健康检查的探针。
|
||||
// ctx 用于取消。单元不存在时返回 false 且无错误;其他检查失败时返回错误。
|
||||
func (o *healthOperation) running(ctx context.Context) (bool, error) {
|
||||
unit, err := o.units.Inspect(ctx, o.unitName)
|
||||
if errors.Is(err, systemd.ErrUnitNotFound) {
|
||||
@@ -252,6 +286,8 @@ func (o *healthOperation) running(ctx context.Context) (bool, error) {
|
||||
return unit.ActiveState == activeState, nil
|
||||
}
|
||||
|
||||
// healthInspection 把健康检查结果归一化为事务检查状态。
|
||||
// report 健康报告;ready 是就绪标志;err 是检查错误。工作负载停止、出错或未就绪均为未应用,否则为已应用。
|
||||
func healthInspection(report healthcheck.ActuatorReport, ready bool, err error) (transaction.Inspection, error) {
|
||||
result := resultJSON(report)
|
||||
if errors.Is(err, healthcheck.ErrWorkloadStopped) {
|
||||
@@ -263,6 +299,8 @@ func healthInspection(report healthcheck.ActuatorReport, ready bool, err error)
|
||||
return transaction.Inspection{Status: transaction.InspectionApplied, Result: result}, nil
|
||||
}
|
||||
|
||||
// linkResult 把槽位路径与目标序列化为 JSON 结果。
|
||||
// path 槽位软链接路径;target 是软链接指向的目标。返回值是序列化后的 JSON。
|
||||
func linkResult(path, target string) json.RawMessage {
|
||||
return resultJSON(struct {
|
||||
Path string `json:"path"`
|
||||
@@ -270,6 +308,8 @@ func linkResult(path, target string) json.RawMessage {
|
||||
}{path, target})
|
||||
}
|
||||
|
||||
// unitResult 把 systemd 单元状态序列化为 JSON 结果。
|
||||
// unit 待序列化的单元。返回值是序列化后的 JSON。
|
||||
func unitResult(unit systemd.Unit) json.RawMessage {
|
||||
return resultJSON(struct {
|
||||
Name string `json:"name"`
|
||||
@@ -279,6 +319,8 @@ func unitResult(unit systemd.Unit) json.RawMessage {
|
||||
}{unit.Name, unit.LoadState, unit.ActiveState, unit.SubState})
|
||||
}
|
||||
|
||||
// resultJSON 把任意值序列化为 JSON 原始消息。
|
||||
// value 待序列化的值。序列化失败时直接 panic(内部结果应始终可序列化)。返回值是序列化后的 JSON。
|
||||
func resultJSON(value any) json.RawMessage {
|
||||
payload, err := json.Marshal(value)
|
||||
if err != nil {
|
||||
@@ -287,6 +329,8 @@ func resultJSON(value any) json.RawMessage {
|
||||
return payload
|
||||
}
|
||||
|
||||
// syncDirectory 打开目录并同步其元数据到磁盘,确保重命名或删除持久化。
|
||||
// path 待刷新的目录路径。返回值是打开、同步或关闭失败时的错误。
|
||||
func syncDirectory(path string) error {
|
||||
directory, err := os.Open(path)
|
||||
if err != nil {
|
||||
@@ -300,6 +344,7 @@ func syncDirectory(path string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// 以下编译期断言确保各操作类型都实现了 transaction.Operation 接口。
|
||||
var _ transaction.Operation = (*installJarOperation)(nil)
|
||||
var _ transaction.Operation = (*slotLinkOperation)(nil)
|
||||
var _ transaction.Operation = (*unitStartOperation)(nil)
|
||||
|
||||
Reference in New Issue
Block a user