split container slot reconciliation

This commit is contained in:
2026-08-22 16:08:07 +08:00
parent a37ee9d09d
commit afa371b250
2 changed files with 50 additions and 30 deletions
+1
View File
@@ -191,5 +191,6 @@
- daemon server 将请求读取、进度回调、更新/重启分派、诊断分派拆开,保留协议错误文本与响应行为。
- `runServe` 将 native/container 运行时构建与资源关闭拆出,避免入口函数承担全部分支。
- 容器槽位现场核对拆为容器检查、已提交部署校验和活动槽位选择,减少单函数分支嵌套。
验证:`GOCACHE=/tmp/yms-go-cache go test ./...``git diff --check` 通过。
+49 -30
View File
@@ -337,40 +337,19 @@ func (u *Updater) resolveContainerSlots(
if err != nil {
return 0, deploymentconfig.BackendSlot{}, "", err
}
active, activeErr := u.engine.InspectContainer(ctx, activeSlot.ContainerName)
if activeErr != nil && !errors.Is(activeErr, containerengine.ErrNotFound) {
return 0, deploymentconfig.BackendSlot{}, "", fmt.Errorf("inspect active backend container %s: %w", activeSlot.ContainerName, activeErr)
active, activeFound, err := u.inspectSlotContainer(ctx, activeSlot.ContainerName, "active")
if err != nil {
return 0, deploymentconfig.BackendSlot{}, "", err
}
inactive, inactiveErr := u.engine.InspectContainer(ctx, inactiveSlot.ContainerName)
if inactiveErr != nil && !errors.Is(inactiveErr, containerengine.ErrNotFound) {
return 0, deploymentconfig.BackendSlot{}, "", fmt.Errorf("inspect inactive backend container %s: %w", inactiveSlot.ContainerName, inactiveErr)
inactive, inactiveFound, err := u.inspectSlotContainer(ctx, inactiveSlot.ContainerName, "inactive")
if err != nil {
return 0, deploymentconfig.BackendSlot{}, "", err
}
activeFound := activeErr == nil
inactiveFound := inactiveErr == nil
if hasDeployment {
if deployment.ActivePort != activePort {
return 0, deploymentconfig.BackendSlot{}, "", fmt.Errorf("committed backend container port %d does not match gateway active port %d", deployment.ActivePort, activePort)
}
if deployment.ContainerName != activeSlot.ContainerName {
return 0, deploymentconfig.BackendSlot{}, "", fmt.Errorf("committed backend container %s does not match gateway slot container %s", deployment.ContainerName, activeSlot.ContainerName)
}
if !activeFound {
return 0, deploymentconfig.BackendSlot{}, "", fmt.Errorf("committed active backend container %s is missing", activeSlot.ContainerName)
}
if active.ID != deployment.ContainerID {
return 0, deploymentconfig.BackendSlot{}, "", fmt.Errorf("active backend container %s identity does not match committed deployment", activeSlot.ContainerName)
}
if err := validateCommittedContainer(deployment, activePort, activeSlot, active, activeFound, hasDeployment); err != nil {
return 0, deploymentconfig.BackendSlot{}, "", err
}
if activeFound {
if !active.Running || active.Dead {
return 0, deploymentconfig.BackendSlot{}, "", fmt.Errorf("active backend container %s is not running", activeSlot.ContainerName)
}
if inactiveFound && inactive.Running && !inactive.Dead {
return 0, deploymentconfig.BackendSlot{}, "", fmt.Errorf("inactive backend container %s is unexpectedly running", inactiveSlot.ContainerName)
}
return inactivePort, inactiveSlot, activeSlot.ContainerName, nil
return selectRunningContainerSlot(inactivePort, activeSlot, inactiveSlot, active, inactive, inactiveFound)
}
if hasHistory {
return 0, deploymentconfig.BackendSlot{}, "", fmt.Errorf("active backend container %s is missing on a server with committed backend container transaction history", activeSlot.ContainerName)
@@ -381,6 +360,46 @@ func (u *Updater) resolveContainerSlots(
return inactivePort, inactiveSlot, "", nil
}
func (u *Updater) inspectSlotContainer(ctx context.Context, name string, role string) (containerengine.Container, bool, error) {
container, err := u.engine.InspectContainer(ctx, name)
if errors.Is(err, containerengine.ErrNotFound) {
return containerengine.Container{}, false, nil
}
if err != nil {
return containerengine.Container{}, false, fmt.Errorf("inspect %s backend container %s: %w", role, name, err)
}
return container, true, nil
}
func validateCommittedContainer(deployment transaction.BackendContainerDeployment, activePort int, activeSlot deploymentconfig.BackendSlot, active containerengine.Container, found bool, hasDeployment bool) error {
if !hasDeployment {
return nil
}
if deployment.ActivePort != activePort {
return fmt.Errorf("committed backend container port %d does not match gateway active port %d", deployment.ActivePort, activePort)
}
if deployment.ContainerName != activeSlot.ContainerName {
return fmt.Errorf("committed backend container %s does not match gateway slot container %s", deployment.ContainerName, activeSlot.ContainerName)
}
if !found {
return fmt.Errorf("committed active backend container %s is missing", activeSlot.ContainerName)
}
if active.ID != deployment.ContainerID {
return fmt.Errorf("active backend container %s identity does not match committed deployment", activeSlot.ContainerName)
}
return nil
}
func selectRunningContainerSlot(inactivePort int, activeSlot, inactiveSlot deploymentconfig.BackendSlot, active, inactive containerengine.Container, inactiveFound bool) (int, deploymentconfig.BackendSlot, string, error) {
if !active.Running || active.Dead {
return 0, deploymentconfig.BackendSlot{}, "", fmt.Errorf("active backend container %s is not running", activeSlot.ContainerName)
}
if inactiveFound && inactive.Running && !inactive.Dead {
return 0, deploymentconfig.BackendSlot{}, "", fmt.Errorf("inactive backend container %s is unexpectedly running", inactiveSlot.ContainerName)
}
return inactivePort, inactiveSlot, activeSlot.ContainerName, nil
}
// resolvedImage 拉取并解析后得到的镜像信息。
type resolvedImage struct {
// ImmutableReference 带摘要的不可变镜像引用。