Ctrl K
ComunidadGuías…

api/handler/cleanup_workload_admission.go

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
package handler

import (
	"crypto/sha256"
	"encoding/hex"

	guard "github.com/goodrain/rainbond/pkg/cleanup"
	"github.com/jinzhu/gorm"
	apierrors "k8s.io/apimachinery/pkg/api/errors"
)

// workloadAdmission outlives individual database transactions so Kubernetes
// requests never run while holding a SQL transaction. Ambiguous effects retain
// the original durable producer records instead of expiring protection.
type workloadAdmission struct {
	database *gorm.DB
	requests []guard.CoordinationRequest
	pending  int
	changed  bool
}

func admitWorkload(database *gorm.DB, body []byte) (*workloadAdmission, error) {
	stores, err := guard.DiscoverStores(database)
	if err != nil {
		return nil, err
	}
	id, err := guard.NewActivationRevision()
	if err != nil {
		return nil, err
	}
	fingerprint := sha256.Sum256(body)
	admission := &workloadAdmission{database: database}
	for _, store := range stores {
		identity := sha256.Sum256([]byte(id + "\x00" + store.StorageID))
		request := guard.CoordinationRequest{StorageID: store.StorageID, Generation: store.Generation, OperationID: hex.EncodeToString(identity[:]), Owner: "api-workload", Kind: "producer", Scope: "*", Fingerprint: hex.EncodeToString(fingerprint[:])}
		created, err := guard.AcquireOperation(database, request)
		if err != nil || !created {
			// No Kubernetes call occurred. Release only admissions definitely created
			// by this invocation, never a rejected or uncertain acquisition.
			_ = admission.finish(true)
			if err != nil {
				return nil, err
			}
			return nil, guard.ErrCoordinationChanged
		}
		admission.requests = append(admission.requests, request)
	}
	return admission, nil
}
func (a *workloadAdmission) finish(confirmed bool) error {
	confirmed = a.pending == 0 && (confirmed || !a.changed)
	var first error
	for _, request := range a.requests {
		if err := guard.FinishOperation(a.database, request, confirmed); err != nil && first == nil {
			first = err
		}
	}
	return first
}
func (a *workloadAdmission) write(write func(*gorm.DB) error) error {
	if len(a.requests) == 0 {
		return write(a.database)
	}
	return guard.WithProducerReferenceMutation(a.database, a.requests, []string{"*"}, write)
}

// observe brackets each Kubernetes mutation. Only explicit API rejection proves
// no effect; transport failures and panics leave the original admission held.
func (a *workloadAdmission) observe(start bool, err error) {
	if start {
		a.pending++
		return
	}
	if err == nil {
		a.changed = true
		a.pending--
		return
	}
	if apierrors.IsAlreadyExists(err) || apierrors.IsConflict(err) || apierrors.IsInvalid(err) || apierrors.IsBadRequest(err) || apierrors.IsForbidden(err) || apierrors.IsUnauthorized(err) || apierrors.IsNotFound(err) || apierrors.IsMethodNotSupported(err) {
		a.pending--
	}
}