mirror of
https://github.com/moby/moby.git
synced 2026-01-11 10:41:43 +00:00
vendor: resenje.org/singleflight v0.4.3
full diff: https://resenje.org/singleflight/compare/v0.4.1...v0.4.3 Changes: - Fix incorrect `Forget` behavior - Make panic behavior consistent with x/sync package Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
This commit is contained in:
@@ -113,7 +113,7 @@ require (
|
||||
google.golang.org/grpc v1.66.3
|
||||
google.golang.org/protobuf v1.35.1
|
||||
gotest.tools/v3 v3.5.1
|
||||
resenje.org/singleflight v0.4.1
|
||||
resenje.org/singleflight v0.4.3
|
||||
tags.cncf.io/container-device-interface v0.8.0
|
||||
)
|
||||
|
||||
|
||||
@@ -801,8 +801,8 @@ kernel.org/pub/linux/libs/security/libcap/cap v1.2.70 h1:QnLPkuDWWbD5C+3DUA2IUXa
|
||||
kernel.org/pub/linux/libs/security/libcap/cap v1.2.70/go.mod h1:/iBwcj9nbLejQitYvUm9caurITQ6WyNHibJk6Q9fiS4=
|
||||
kernel.org/pub/linux/libs/security/libcap/psx v1.2.70 h1:HsB2G/rEQiYyo1bGoQqHZ/Bvd6x1rERQTNdPr1FyWjI=
|
||||
kernel.org/pub/linux/libs/security/libcap/psx v1.2.70/go.mod h1:+l6Ee2F59XiJ2I6WR5ObpC1utCQJZ/VLsEbQCD8RG24=
|
||||
resenje.org/singleflight v0.4.1 h1:ryGHRaOBwhnZLyf34LMDf4AsTSHrs4hdGPdG/I4Hmac=
|
||||
resenje.org/singleflight v0.4.1/go.mod h1:lAgQK7VfjG6/pgredbQfmV0RvG/uVhKo6vSuZ0vCWfk=
|
||||
resenje.org/singleflight v0.4.3 h1:l7foFYg8X/VEHPxWs1K/Pw77807RMVzvXgWGb0J1sdM=
|
||||
resenje.org/singleflight v0.4.3/go.mod h1:lAgQK7VfjG6/pgredbQfmV0RvG/uVhKo6vSuZ0vCWfk=
|
||||
sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8=
|
||||
sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E=
|
||||
sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY=
|
||||
|
||||
2
vendor/modules.txt
vendored
2
vendor/modules.txt
vendored
@@ -1597,7 +1597,7 @@ k8s.io/klog/v2/internal/clock
|
||||
k8s.io/klog/v2/internal/dbg
|
||||
k8s.io/klog/v2/internal/serialize
|
||||
k8s.io/klog/v2/internal/severity
|
||||
# resenje.org/singleflight v0.4.1
|
||||
# resenje.org/singleflight v0.4.3
|
||||
## explicit; go 1.18
|
||||
resenje.org/singleflight
|
||||
# sigs.k8s.io/yaml v1.4.0
|
||||
|
||||
36
vendor/resenje.org/singleflight/.golangci.yaml
generated
vendored
Normal file
36
vendor/resenje.org/singleflight/.golangci.yaml
generated
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
run:
|
||||
timeout: 10m
|
||||
allow-parallel-runners: true
|
||||
|
||||
linters:
|
||||
enable:
|
||||
- errname
|
||||
- stylecheck
|
||||
- importas
|
||||
- errcheck
|
||||
- gosimple
|
||||
- govet
|
||||
- ineffassign
|
||||
- mirror
|
||||
- staticcheck
|
||||
- tagalign
|
||||
- testifylint
|
||||
- typecheck
|
||||
- unused
|
||||
- unconvert
|
||||
- wastedassign
|
||||
- whitespace
|
||||
- gocritic
|
||||
- exhaustive
|
||||
- noctx
|
||||
- promlinter
|
||||
# TODO these fail on windows
|
||||
# - gofmt
|
||||
# - goimports
|
||||
|
||||
linters-settings:
|
||||
govet:
|
||||
enable-all: true
|
||||
disable:
|
||||
- shadow
|
||||
- fieldalignment
|
||||
9
vendor/resenje.org/singleflight/README.md
generated
vendored
9
vendor/resenje.org/singleflight/README.md
generated
vendored
@@ -3,9 +3,12 @@
|
||||
[](https://godoc.org/resenje.org/singleflight)
|
||||
[](https://github.com/janos/singleflight/actions?query=workflow%3AGo)
|
||||
|
||||
Package singleflight provides a duplicate function call suppression
|
||||
mechanism similar to golang.org/x/sync/singleflight but with support
|
||||
for context cancelation.
|
||||
Package singleflight provides a duplicate function call suppression
|
||||
mechanism similar to [golang.org/x/sync/singleflight](https://pkg.go.dev/golang.org/x/sync/singleflight) but with:
|
||||
|
||||
- support for context cancelation. The context passed to the callback function is a context that preserves all values
|
||||
from the passed context but is cancelled by the singleflight only when all awaiting caller's contexts are cancelled.
|
||||
- support for generics.
|
||||
|
||||
## Installation
|
||||
|
||||
|
||||
55
vendor/resenje.org/singleflight/singleflight.go
generated
vendored
55
vendor/resenje.org/singleflight/singleflight.go
generated
vendored
@@ -10,11 +10,36 @@ package singleflight
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"runtime/debug"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// A panicError is an arbitrary value recovered from a panic
|
||||
// with the stack trace during the execution of given function.
|
||||
type panicError struct {
|
||||
value interface{}
|
||||
stack []byte
|
||||
}
|
||||
|
||||
// Error implements error interface.
|
||||
func (p *panicError) Error() string {
|
||||
return fmt.Sprintf("%v\n\n%s", p.value, p.stack)
|
||||
}
|
||||
|
||||
func (p *panicError) Unwrap() error {
|
||||
err, ok := p.value.(error)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// Group represents a class of work and forms a namespace in
|
||||
// which units of work can be executed with duplicate suppression.
|
||||
// K is the type of the key used for deduplication, and V is
|
||||
// the return value of the work function.
|
||||
type Group[K comparable, V any] struct {
|
||||
calls map[K]*call[V] // lazily initialized
|
||||
mu sync.Mutex // protects calls
|
||||
@@ -60,8 +85,14 @@ func (g *Group[K, V]) Do(ctx context.Context, key K, fn func(ctx context.Context
|
||||
g.mu.Unlock()
|
||||
|
||||
go func() {
|
||||
defer func() {
|
||||
if v := recover(); v != nil {
|
||||
c.panicErr = &panicError{value: v, stack: debug.Stack()}
|
||||
}
|
||||
close(c.done)
|
||||
}()
|
||||
|
||||
c.val, c.err = fn(callCtx)
|
||||
close(c.done)
|
||||
}()
|
||||
|
||||
return g.wait(ctx, key, c)
|
||||
@@ -69,10 +100,12 @@ func (g *Group[K, V]) Do(ctx context.Context, key K, fn func(ctx context.Context
|
||||
|
||||
// wait for function passed to Do to finish or context to be done.
|
||||
func (g *Group[K, V]) wait(ctx context.Context, key K, c *call[V]) (v V, shared bool, err error) {
|
||||
var panicErr *panicError
|
||||
select {
|
||||
case <-c.done:
|
||||
v = c.val
|
||||
err = c.err
|
||||
panicErr = c.panicErr
|
||||
case <-ctx.Done():
|
||||
err = ctx.Err()
|
||||
}
|
||||
@@ -80,10 +113,17 @@ func (g *Group[K, V]) wait(ctx context.Context, key K, c *call[V]) (v V, shared
|
||||
c.counter--
|
||||
if c.counter == 0 {
|
||||
c.cancel()
|
||||
delete(g.calls, key)
|
||||
if !c.forgotten {
|
||||
delete(g.calls, key)
|
||||
}
|
||||
}
|
||||
shared = c.shared
|
||||
g.mu.Unlock()
|
||||
|
||||
if panicErr != nil {
|
||||
panic(panicErr)
|
||||
}
|
||||
|
||||
return v, shared, err
|
||||
}
|
||||
|
||||
@@ -92,6 +132,9 @@ func (g *Group[K, V]) wait(ctx context.Context, key K, c *call[V]) (v V, shared
|
||||
// an earlier call to complete.
|
||||
func (g *Group[K, V]) Forget(key K) {
|
||||
g.mu.Lock()
|
||||
if c, ok := g.calls[key]; ok {
|
||||
c.forgotten = true
|
||||
}
|
||||
delete(g.calls, key)
|
||||
g.mu.Unlock()
|
||||
}
|
||||
@@ -102,6 +145,10 @@ type call[V any] struct {
|
||||
val V
|
||||
err error
|
||||
|
||||
// panicError wraps the value passed to panic() if the function call panicked.
|
||||
// val and err should be ignored if this is non-nil.
|
||||
panicErr *panicError
|
||||
|
||||
// done channel signals that the function call is done.
|
||||
done chan struct{}
|
||||
|
||||
@@ -113,4 +160,8 @@ type call[V any] struct {
|
||||
|
||||
// shared indicates if results val and err are passed to multiple callers.
|
||||
shared bool
|
||||
|
||||
// forgotten indicates whether Forget was called with this call's key
|
||||
// while the call was still in flight.
|
||||
forgotten bool
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user