refactor: split container switch and commit steps

This commit is contained in:
2026-08-22 15:57:03 +08:00
parent a81f81e347
commit 3f13130b8a
+31 -22
View File
@@ -517,25 +517,47 @@ func (u *Updater) switchAndCommitContainer(ctx context.Context, transactionID st
}
switch record.State {
case transaction.StateSwitching:
reportProgress(report, Progress{TransactionID: transactionID, State: record.State, Message: fmt.Sprintf("Switching host Nginx backend traffic to port %d", request.TargetPort)})
if err := u.switchContainerTraffic(ctx, transactionID, request, before, after, report); err != nil {
return err
}
case transaction.StateVerifying:
if err := u.markContainerDraining(ctx, transactionID, request); err != nil {
return err
}
case transaction.StateDraining:
return u.drainAndCommitContainer(ctx, transactionID, request, report)
case transaction.StateCommitted:
return nil
case transaction.StateRollingBack:
return u.rollbackContainer(ctx, transactionID, request, before, after, errors.New("resuming container backend rollback"))
default:
return fmt.Errorf("container backend commit cannot continue transaction %s in state %s", transactionID, record.State)
}
}
}
func (u *Updater) switchContainerTraffic(ctx context.Context, transactionID string, request persistedContainerRequest, before hostnginx.Snapshot, after hostnginx.Snapshot, report ProgressReporter) error {
reportProgress(report, Progress{TransactionID: transactionID, State: transaction.StateSwitching, Message: fmt.Sprintf("Switching host Nginx backend traffic to port %d", request.TargetPort)})
operation := &gatewayOperation{controller: u.gateway, before: before, after: after, receiptPath: request.GatewayReceiptPath}
if _, err := u.coordinator.ExecuteStep(ctx, transactionID, containerGatewaySwitchIntent(request), operation); err != nil {
return u.rollbackContainer(ctx, transactionID, request, before, after, err)
}
if _, err := u.store.Transition(ctx, transactionID, transaction.StateVerifying, "host Nginx now routes backend traffic to the healthy container slot"); err != nil {
_, err := u.store.Transition(ctx, transactionID, transaction.StateVerifying, "host Nginx now routes backend traffic to the healthy container slot")
return err
}
case transaction.StateVerifying:
}
func (u *Updater) markContainerDraining(ctx context.Context, transactionID string, request persistedContainerRequest) error {
message := "container backend switch verified"
if request.PreviousContainer != "" {
message += "; previous container draining"
}
if _, err := u.store.Transition(ctx, transactionID, transaction.StateDraining, message); err != nil {
_, err := u.store.Transition(ctx, transactionID, transaction.StateDraining, message)
return err
}
case transaction.StateDraining:
}
func (u *Updater) drainAndCommitContainer(ctx context.Context, transactionID string, request persistedContainerRequest, report ProgressReporter) error {
if request.PreviousContainer != "" {
reportProgress(report, Progress{TransactionID: transactionID, State: record.State, Message: fmt.Sprintf("Draining previous backend container for %s", u.drain)})
reportProgress(report, Progress{TransactionID: transactionID, State: transaction.StateDraining, Message: fmt.Sprintf("Draining previous backend container for %s", u.drain)})
if err := waitContext(ctx, u.drain); err != nil {
return err
}
@@ -554,24 +576,11 @@ func (u *Updater) switchAndCommitContainer(ctx context.Context, transactionID st
if target.ImageReference != request.ImmutableReference && target.ImageReference != request.ImageReference {
return fmt.Errorf("target backend container %s image reference does not match the transaction", request.TargetContainer)
}
_, err = u.store.CommitBackendContainerDeployment(ctx, transactionID, transaction.BackendContainerDeployment{
ActivePort: request.TargetPort,
ContainerName: request.TargetContainer,
ImageDigest: request.ImageDigest,
ContainerID: target.ID,
}, "container backend update committed")
_, err = u.store.CommitBackendContainerDeployment(ctx, transactionID, transaction.BackendContainerDeployment{ActivePort: request.TargetPort, ContainerName: request.TargetContainer, ImageDigest: request.ImageDigest, ContainerID: target.ID}, "container backend update committed")
if err == nil {
reportProgress(report, Progress{TransactionID: transactionID, State: transaction.StateCommitted, Message: "Container backend update committed"})
}
return err
case transaction.StateCommitted:
return nil
case transaction.StateRollingBack:
return u.rollbackContainer(ctx, transactionID, request, before, after, errors.New("resuming container backend rollback"))
default:
return fmt.Errorf("container backend commit cannot continue transaction %s in state %s", transactionID, record.State)
}
}
}
// rollbackContainer 执行容器后端补偿:恢复 Nginx 上游、停止被补偿的目标容器,并