Files
buildkit/solver/result.go
Tonis Tiigi 98e1113c6d lint: modernize Go lint findings
Update non-generated code for the newer lint recommendations by using typed
atomic values, strings.Cut, and slices.Backward where applicable.

Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2026-05-14 10:13:21 -07:00

134 lines
2.7 KiB
Go

package solver
import (
"context"
"sync"
"sync/atomic"
"github.com/moby/buildkit/util/bklog"
"github.com/pkg/errors"
)
// SharedResult is a result that can be cloned
type SharedResult struct {
mu sync.Mutex
main Result
}
func NewSharedResult(main Result) *SharedResult {
return &SharedResult{main: main}
}
func (r *SharedResult) Clone() Result {
r.mu.Lock()
defer r.mu.Unlock()
r1, r2 := dup(r.main)
r.main = r1
return r2
}
func (r *SharedResult) Release(ctx context.Context) error {
r.mu.Lock()
defer r.mu.Unlock()
return r.main.Release(ctx)
}
func dup(res Result) (Result, Result) {
var sem atomic.Int64
return &splitResult{Result: res, sem: &sem}, &splitResult{Result: res, sem: &sem}
}
type splitResult struct {
released atomic.Int64
sem *atomic.Int64
Result
}
func (r *splitResult) Release(ctx context.Context) error {
if r.released.Add(1) > 1 {
err := errors.Errorf("releasing already released reference %+v", r.ID())
bklog.G(ctx).Error(err)
return err
}
if r.sem.Add(1) == 2 {
return r.Result.Release(ctx)
}
return nil
}
// NewCachedResult combines a result and cache key into cached result
func NewCachedResult(res Result, k []ExportableCacheKey) CachedResult {
return &cachedResult{res, k}
}
type cachedResult struct {
Result
k []ExportableCacheKey
}
func (cr *cachedResult) CacheKeys() []ExportableCacheKey {
return cr.k
}
func NewSharedCachedResult(res CachedResult) *SharedCachedResult {
return &SharedCachedResult{
SharedResult: NewSharedResult(res),
CachedResult: res,
}
}
func (r *SharedCachedResult) CloneCachedResult() CachedResult {
return &clonedCachedResult{Result: r.SharedResult.Clone(), cr: r.CachedResult}
}
func (r *SharedCachedResult) Clone() Result {
return r.CloneCachedResult()
}
func (r *SharedCachedResult) Release(ctx context.Context) error {
return r.SharedResult.Release(ctx)
}
type clonedCachedResult struct {
Result
cr CachedResult
}
func (ccr *clonedCachedResult) ID() string {
return ccr.Result.ID()
}
func (ccr *clonedCachedResult) CacheKeys() []ExportableCacheKey {
return ccr.cr.CacheKeys()
}
type SharedCachedResult struct {
*SharedResult
CachedResult
}
type splitResultProxy struct {
released atomic.Int64
sem *atomic.Int64
ResultProxy
}
func (r *splitResultProxy) Release(ctx context.Context) error {
if r.released.Add(1) > 1 {
err := errors.New("releasing already released reference")
bklog.G(ctx).Error(err)
return err
}
if r.sem.Add(1) == 2 {
return r.ResultProxy.Release(ctx)
}
return nil
}
func SplitResultProxy(res ResultProxy) (ResultProxy, ResultProxy) {
var sem atomic.Int64
return &splitResultProxy{ResultProxy: res, sem: &sem}, &splitResultProxy{ResultProxy: res, sem: &sem}
}