mirror of
https://github.com/owncloud/ocis.git
synced 2026-10-23 23:29:02 +03:00
chore: bump reva to fix/ocisdev-855-main for load-test comparison
This commit is contained in:
2
go.mod
2
go.mod
@@ -67,7 +67,7 @@ require (
|
||||
github.com/open-policy-agent/opa v1.21.1
|
||||
github.com/orcaman/concurrent-map v1.0.0
|
||||
github.com/owncloud/libre-graph-api-go v1.0.5-0.20260216101009-eeac018af245
|
||||
github.com/owncloud/reva/v2 v2.0.0-20261012083840-8b649a4c3899
|
||||
github.com/owncloud/reva/v2 v2.0.0-20261013125910-ed54ed63ad22
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/pkg/xattr v0.4.12
|
||||
github.com/prometheus/client_golang v1.24.1
|
||||
|
||||
4
go.sum
4
go.sum
@@ -736,8 +736,8 @@ github.com/orcaman/concurrent-map v1.0.0 h1:I/2A2XPCb4IuQWcQhBhSwGfiuybl/J0ev9HD
|
||||
github.com/orcaman/concurrent-map v1.0.0/go.mod h1:Lu3tH6HLW3feq74c2GC+jIMS/K2CFcDWnWD9XkenwhI=
|
||||
github.com/owncloud/libre-graph-api-go v1.0.5-0.20260216101009-eeac018af245 h1:JRidLTAKhnvyLMRtVtSF4lhBa0NSAOs6fof+d6JnKII=
|
||||
github.com/owncloud/libre-graph-api-go v1.0.5-0.20260216101009-eeac018af245/go.mod h1:z61VMGAJRtR1nbgXWiNoCkxUXP1B3Je9rMuJbnGd+Og=
|
||||
github.com/owncloud/reva/v2 v2.0.0-20261012083840-8b649a4c3899 h1:IMu076AtnFEdabpBbowcGDYOeFLtm9ycNY1Z43YPYZU=
|
||||
github.com/owncloud/reva/v2 v2.0.0-20261012083840-8b649a4c3899/go.mod h1:cgqg+UTe4ekjMbJj8hgoXSTxQ9fQramKcOUdvsFUrzc=
|
||||
github.com/owncloud/reva/v2 v2.0.0-20261013125910-ed54ed63ad22 h1:/4AAImjYT1wJ0zCf3DWZS8GwiVWQKi2EQbjmmg07TNM=
|
||||
github.com/owncloud/reva/v2 v2.0.0-20261013125910-ed54ed63ad22/go.mod h1:cgqg+UTe4ekjMbJj8hgoXSTxQ9fQramKcOUdvsFUrzc=
|
||||
github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c h1:rp5dCmg/yLR3mgFuSOe4oEnDDmGLROTvMragMUXpTQw=
|
||||
github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c/go.mod h1:X07ZCGwUbLaax7L0S3Tw4hpejzu63ZrrQiUe6W0hcy0=
|
||||
github.com/pablodz/inotifywaitgo v0.0.12 h1:DVJJTFMDlSAdO46yisPF2vzozs/r+4k6ih8MVghq78M=
|
||||
|
||||
@@ -463,6 +463,10 @@ func (s *Service) InitiateFileUpload(ctx context.Context, req *provider.Initiate
|
||||
st = status.NewInsufficientStorage(ctx, err, "insufficient storage")
|
||||
case errtypes.PreconditionFailed:
|
||||
st = status.NewFailedPrecondition(ctx, err, "failed precondition")
|
||||
case errtypes.Aborted:
|
||||
st = status.NewAborted(ctx, err, "response from InitiateUpload")
|
||||
case errtypes.AlreadyExists:
|
||||
st = status.NewAlreadyExists(ctx, err, "response from InitiateUpload")
|
||||
case errtypes.Locked:
|
||||
st = status.NewLocked(ctx, "locked")
|
||||
case errtypes.IsTooEarly:
|
||||
|
||||
21
vendor/github.com/owncloud/reva/v2/pkg/errtypes/errtypes.go
generated
vendored
21
vendor/github.com/owncloud/reva/v2/pkg/errtypes/errtypes.go
generated
vendored
@@ -24,6 +24,7 @@ package errtypes
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
rpc "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1"
|
||||
@@ -213,6 +214,14 @@ func (e TooManyRequests) Error() string { return "error: too many requests: " +
|
||||
// IsTooManyRequests implements the IsTooManyRequests interface
|
||||
func (e TooManyRequests) IsTooManyRequests() {}
|
||||
|
||||
// Unavailable is the error to use when the upstream is temporarily unable to handle the request (502/503/504).
|
||||
type Unavailable string
|
||||
|
||||
func (e Unavailable) Error() string { return "error: unavailable: " + string(e) }
|
||||
|
||||
// IsUnavailable implements the IsUnavailable interface.
|
||||
func (e Unavailable) IsUnavailable() {}
|
||||
|
||||
// IsNotFound is the interface to implement
|
||||
// to specify that a resource is not found.
|
||||
type IsNotFound interface {
|
||||
@@ -309,6 +318,12 @@ type IsTooManyRequests interface {
|
||||
IsTooManyRequests()
|
||||
}
|
||||
|
||||
// IsUnavailable is the interface to implement
|
||||
// to specify that the upstream is temporarily unavailable.
|
||||
type IsUnavailable interface {
|
||||
IsUnavailable()
|
||||
}
|
||||
|
||||
// ResourceProcessing is the error to use when a resource is currently being processed (e.g. an upload in progress) and the requested operation cannot proceed.
|
||||
type ResourceProcessing string
|
||||
|
||||
@@ -395,8 +410,10 @@ func NewErrtypeFromHTTPStatusCode(code int, message string) error {
|
||||
return TooManyRequests(message)
|
||||
case StatusChecksumMismatch:
|
||||
return ChecksumMismatch(message)
|
||||
case http.StatusBadGateway, http.StatusServiceUnavailable, http.StatusGatewayTimeout:
|
||||
return Unavailable(message)
|
||||
default:
|
||||
return InternalError(message)
|
||||
return InternalError("http " + strconv.Itoa(code) + ": " + message)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -433,6 +450,8 @@ func NewHTTPStatusCodeFromErrtype(err error) int {
|
||||
return http.StatusTooEarly
|
||||
case TooManyRequests:
|
||||
return http.StatusTooManyRequests
|
||||
case Unavailable:
|
||||
return http.StatusServiceUnavailable
|
||||
case ChecksumMismatch:
|
||||
return StatusChecksumMismatch
|
||||
default:
|
||||
|
||||
@@ -208,12 +208,15 @@ func (c *Cache) Add(ctx context.Context, storageID, spaceID, shareID string, sha
|
||||
// CS3 uses an already exists error instead of precondition failed when using an If-None-Match=* header / IfExists flag in the InitiateFileUpload call.
|
||||
// Thas happens when the cache thinks there is no file.
|
||||
// continue with sync below
|
||||
case errtypes.TooEarly:
|
||||
log.Debug().Msg("too early when persisting added provider share: write-lock contention. retrying...")
|
||||
// continue with sync below
|
||||
default:
|
||||
span.SetStatus(codes.Error, fmt.Sprintf("persisting added provider share failed. giving up: %s", err.Error()))
|
||||
log.Error().Err(err).Msg("persisting added provider share failed")
|
||||
return err
|
||||
}
|
||||
if err := c.syncWithLock(ctx, storageID, spaceID); err != nil {
|
||||
if err := c.resyncAfterConflict(ctx, storageID, spaceID); err != nil {
|
||||
span.RecordError(err)
|
||||
span.SetStatus(codes.Error, err.Error())
|
||||
log.Error().Err(err).Msg("persisting added provider share failed. giving up.")
|
||||
@@ -276,12 +279,15 @@ func (c *Cache) Remove(ctx context.Context, storageID, spaceID, shareID string)
|
||||
log.Debug().Msg("precondition failed when persisting removed provider share: etag changed. retrying...")
|
||||
// actually, this is the wrong status code and we treat it like errtypes.Aborted because of inconsistencies on the server side
|
||||
// continue with sync below
|
||||
case errtypes.TooEarly:
|
||||
log.Debug().Msg("too early when persisting removed provider share: write-lock contention. retrying...")
|
||||
// continue with sync below
|
||||
default:
|
||||
span.SetStatus(codes.Error, fmt.Sprintf("persisting removed provider share failed. giving up: %s", err.Error()))
|
||||
log.Error().Err(err).Msg("persisting removed provider share failed")
|
||||
return err
|
||||
}
|
||||
if err := c.syncWithLock(ctx, storageID, spaceID); err != nil {
|
||||
if err := c.resyncAfterConflict(ctx, storageID, spaceID); err != nil {
|
||||
span.RecordError(err)
|
||||
span.SetStatus(codes.Error, err.Error())
|
||||
log.Error().Err(err).Msg("persisting removed provider share failed. giving up.")
|
||||
@@ -479,6 +485,16 @@ func (c *Cache) PurgeSpace(ctx context.Context, storageID, spaceID string) error
|
||||
}
|
||||
|
||||
func (c *Cache) syncWithLock(ctx context.Context, storageID, spaceID string) error {
|
||||
return c.doSync(ctx, storageID, spaceID, true)
|
||||
}
|
||||
|
||||
// Unlike syncWithLock, a NotFound here must not reset the cache -- a pending
|
||||
// mutation is about to overwrite it, dropping a sibling writer's data.
|
||||
func (c *Cache) resyncAfterConflict(ctx context.Context, storageID, spaceID string) error {
|
||||
return c.doSync(ctx, storageID, spaceID, false)
|
||||
}
|
||||
|
||||
func (c *Cache) doSync(ctx context.Context, storageID, spaceID string, resetOnNotFound bool) error {
|
||||
ctx, span := tracer.Start(ctx, "syncWithLock")
|
||||
defer span.End()
|
||||
|
||||
@@ -502,6 +518,13 @@ func (c *Cache) syncWithLock(ctx context.Context, storageID, spaceID string) err
|
||||
case nil:
|
||||
span.AddEvent("updating local cache")
|
||||
case errtypes.NotFound:
|
||||
// No prior etag means this is a bootstrap race, not a lost update -- safe to reset.
|
||||
if !resetOnNotFound && space.Etag != "" {
|
||||
span.RecordError(err)
|
||||
span.SetStatus(codes.Error, err.Error())
|
||||
log.Error().Err(err).Msg("lost update: backing file disappeared mid-retry")
|
||||
return err
|
||||
}
|
||||
span.SetStatus(codes.Ok, "")
|
||||
if err := c.Persist(ctx, storageID, spaceID); err != nil {
|
||||
log.Warn().Err(err).Msg("failed to create empty provider cache file")
|
||||
|
||||
@@ -223,10 +223,12 @@ func (c *Cache) List(ctx context.Context, userID string) (map[string]*Space, err
|
||||
return spaces, nil
|
||||
}
|
||||
|
||||
// isSyncTransient reports whether a resync's Download error is worth retrying.
|
||||
// errtypes.InternalError is excluded on purpose -- retrying a permanent failure just burns the budget.
|
||||
func isSyncTransient(err error) bool {
|
||||
_, isTooEarly := err.(errtypes.IsTooEarly)
|
||||
_, isInternal := err.(errtypes.IsInternalError)
|
||||
return isTooEarly || isInternal
|
||||
_, isUnavailable := err.(errtypes.IsUnavailable)
|
||||
return isTooEarly || isUnavailable
|
||||
}
|
||||
|
||||
func (c *Cache) retryPersist(ctx context.Context, userID, spaceID string, persistFunc func() error) error {
|
||||
@@ -274,12 +276,23 @@ func (c *Cache) retryPersist(ctx context.Context, userID, spaceID string, persis
|
||||
timer.Stop()
|
||||
return ctx.Err()
|
||||
}
|
||||
if serr := c.syncIfStale(ctx, userID); serr != nil {
|
||||
if !isSyncTransient(serr) {
|
||||
log.Error().Int("attempt", attempt).Err(serr).Msg("lost update: re-read failed, aborting")
|
||||
return serr
|
||||
serr := c.resyncAfterConflict(ctx, userID)
|
||||
// Retrying persistFunc now would just repeat the same conflict against stale
|
||||
// state -- keep retrying the resync itself until it refreshes that state.
|
||||
for resyncAttempt := 0; serr != nil && isSyncTransient(serr) && resyncAttempt < 20; resyncAttempt++ {
|
||||
log.Warn().Int("attempt", attempt).Int("resyncAttempt", resyncAttempt).Err(serr).Msg("lost update: re-read before retry")
|
||||
timer := time.NewTimer(expBackoff(resyncAttempt))
|
||||
select {
|
||||
case <-timer.C:
|
||||
case <-ctx.Done():
|
||||
timer.Stop()
|
||||
return ctx.Err()
|
||||
}
|
||||
log.Warn().Int("attempt", attempt).Err(serr).Msg("lost update: re-read before retry")
|
||||
serr = c.resyncAfterConflict(ctx, userID)
|
||||
}
|
||||
if serr != nil {
|
||||
log.Error().Int("attempt", attempt).Err(serr).Msg("lost update: re-read failed, aborting")
|
||||
return serr
|
||||
}
|
||||
}
|
||||
return err
|
||||
@@ -287,6 +300,16 @@ func (c *Cache) retryPersist(ctx context.Context, userID, spaceID string, persis
|
||||
|
||||
// syncIfStale pulls the authoritative state from storage when the local replica is stale; caller must hold the user lock.
|
||||
func (c *Cache) syncIfStale(ctx context.Context, userID string) error {
|
||||
return c.doSync(ctx, userID, true)
|
||||
}
|
||||
|
||||
// Unlike syncIfStale, a NotFound here must not reset the cache -- a pending
|
||||
// mutation is about to overwrite it, dropping a sibling writer's data.
|
||||
func (c *Cache) resyncAfterConflict(ctx context.Context, userID string) error {
|
||||
return c.doSync(ctx, userID, false)
|
||||
}
|
||||
|
||||
func (c *Cache) doSync(ctx context.Context, userID string, resetOnNotFound bool) error {
|
||||
ctx, span := appctx.GetTracerProvider(ctx).Tracer(tracerName).Start(ctx, "SyncIfStale")
|
||||
defer span.End()
|
||||
span.SetAttributes(attribute.String("cs3.userid", userID))
|
||||
@@ -299,6 +322,7 @@ func (c *Cache) syncIfStale(ctx context.Context, userID string) error {
|
||||
span.AddEvent("updating cache")
|
||||
// - update cached list of created shares for the user in memory if changed
|
||||
rss, _ := c.ReceivedSpaces.Load(userID)
|
||||
hadEtag := rss.etag != ""
|
||||
dlres, err := c.storage.Download(ctx, metadata.DownloadRequest{
|
||||
Path: jsonPath,
|
||||
IfNoneMatch: []string{rss.etag},
|
||||
@@ -307,6 +331,12 @@ func (c *Cache) syncIfStale(ctx context.Context, userID string) error {
|
||||
case nil:
|
||||
span.AddEvent("updating local cache")
|
||||
case errtypes.NotFound:
|
||||
// No prior etag means this is a bootstrap race, not a lost update -- safe to reset.
|
||||
if !resetOnNotFound && hadEtag {
|
||||
span.SetStatus(codes.Error, err.Error())
|
||||
log.Error().Err(err).Msg("lost update: backing file disappeared mid-retry")
|
||||
return err
|
||||
}
|
||||
span.SetStatus(codes.Ok, "")
|
||||
if err := c.persist(ctx, userID); err != nil {
|
||||
log.Warn().Err(err).Msg("failed to create empty received share cache file")
|
||||
|
||||
28
vendor/github.com/owncloud/reva/v2/pkg/share/manager/jsoncs3/sharecache/sharecache.go
generated
vendored
28
vendor/github.com/owncloud/reva/v2/pkg/share/manager/jsoncs3/sharecache/sharecache.go
generated
vendored
@@ -144,12 +144,15 @@ func (c *Cache) Add(ctx context.Context, userid, shareID string) error {
|
||||
// CS3 uses an already exists error instead of precondition failed when using an If-None-Match=* header / IfExists flag in the InitiateFileUpload call.
|
||||
// Thas happens when the cache thinks there is no file.
|
||||
// continue with sync below
|
||||
case errtypes.TooEarly:
|
||||
log.Debug().Msg("too early when persisting added share: write-lock contention. retrying...")
|
||||
// continue with sync below
|
||||
default:
|
||||
span.SetStatus(codes.Error, fmt.Sprintf("persisting added share failed. giving up: %s", err.Error()))
|
||||
log.Error().Err(err).Msg("persisting added share failed")
|
||||
return err
|
||||
}
|
||||
if err := c.syncWithLock(ctx, userid); err != nil {
|
||||
if err := c.resyncAfterConflict(ctx, userid); err != nil {
|
||||
span.RecordError(err)
|
||||
span.SetStatus(codes.Error, err.Error())
|
||||
log.Error().Err(err).Msg("persisting added share failed. giving up.")
|
||||
@@ -219,12 +222,15 @@ func (c *Cache) Remove(ctx context.Context, userid, shareID string) error {
|
||||
// CS3 uses an already exists error instead of precondition failed when using an If-None-Match=* header / IfExists flag in the InitiateFileUpload call.
|
||||
// Thas happens when the cache thinks there is no file.
|
||||
// continue with sync below
|
||||
case errtypes.TooEarly:
|
||||
log.Debug().Msg("too early when persisting removed share: write-lock contention. retrying...")
|
||||
// continue with sync below
|
||||
default:
|
||||
span.SetStatus(codes.Error, fmt.Sprintf("persisting removed share failed. giving up: %s", err.Error()))
|
||||
log.Error().Err(err).Msg("persisting removed share failed")
|
||||
return err
|
||||
}
|
||||
if err := c.syncWithLock(ctx, userid); err != nil {
|
||||
if err := c.resyncAfterConflict(ctx, userid); err != nil {
|
||||
span.RecordError(err)
|
||||
span.SetStatus(codes.Error, err.Error())
|
||||
return err
|
||||
@@ -260,6 +266,16 @@ func (c *Cache) List(ctx context.Context, userid string) (map[string]SpaceShareI
|
||||
}
|
||||
|
||||
func (c *Cache) syncWithLock(ctx context.Context, userID string) error {
|
||||
return c.doSync(ctx, userID, true)
|
||||
}
|
||||
|
||||
// Unlike syncWithLock, a NotFound here must not reset the cache -- a pending
|
||||
// mutation is about to overwrite it, dropping a sibling writer's data.
|
||||
func (c *Cache) resyncAfterConflict(ctx context.Context, userID string) error {
|
||||
return c.doSync(ctx, userID, false)
|
||||
}
|
||||
|
||||
func (c *Cache) doSync(ctx context.Context, userID string, resetOnNotFound bool) error {
|
||||
ctx, span := appctx.GetTracerProvider(ctx).Tracer(tracerName).Start(ctx, "Sync")
|
||||
defer span.End()
|
||||
span.SetAttributes(attribute.String("cs3.userid", userID))
|
||||
@@ -274,7 +290,9 @@ func (c *Cache) syncWithLock(ctx context.Context, userID string) error {
|
||||
dlreq := metadata.DownloadRequest{
|
||||
Path: userCreatedPath,
|
||||
}
|
||||
var hadEtag bool
|
||||
if us, ok := c.UserShares.Load(userID); ok && us.Etag != "" {
|
||||
hadEtag = true
|
||||
dlreq.IfNoneMatch = []string{us.Etag}
|
||||
}
|
||||
|
||||
@@ -283,6 +301,12 @@ func (c *Cache) syncWithLock(ctx context.Context, userID string) error {
|
||||
case nil:
|
||||
span.AddEvent("updating local cache")
|
||||
case errtypes.NotFound:
|
||||
// No prior etag means this is a bootstrap race, not a lost update -- safe to reset.
|
||||
if !resetOnNotFound && hadEtag {
|
||||
span.SetStatus(codes.Error, err.Error())
|
||||
log.Error().Err(err).Msg("lost update: backing file disappeared mid-retry")
|
||||
return err
|
||||
}
|
||||
span.SetStatus(codes.Ok, "")
|
||||
if err := c.Persist(ctx, userID); err != nil {
|
||||
log.Warn().Err(err).Msg("failed to create empty share cache file")
|
||||
|
||||
4
vendor/github.com/owncloud/reva/v2/pkg/storage/fs/ocis/blobstore/blobstore.go
generated
vendored
4
vendor/github.com/owncloud/reva/v2/pkg/storage/fs/ocis/blobstore/blobstore.go
generated
vendored
@@ -26,6 +26,7 @@ import (
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/owncloud/reva/v2/pkg/errtypes"
|
||||
"github.com/owncloud/reva/v2/pkg/storage/utils/decomposedfs/lookup"
|
||||
"github.com/owncloud/reva/v2/pkg/storage/utils/decomposedfs/node"
|
||||
"github.com/owncloud/reva/v2/pkg/utils"
|
||||
@@ -155,6 +156,9 @@ func (bs *Blobstore) Download(node *node.Node) (io.ReadCloser, error) {
|
||||
dest := bs.Path(node)
|
||||
file, err := os.Open(dest)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return nil, errtypes.NotFound(dest)
|
||||
}
|
||||
return nil, errors.Wrapf(err, "could not read blob '%s'", dest)
|
||||
}
|
||||
return file, nil
|
||||
|
||||
3
vendor/github.com/owncloud/reva/v2/pkg/storage/utils/decomposedfs/decomposedfs.go
generated
vendored
3
vendor/github.com/owncloud/reva/v2/pkg/storage/utils/decomposedfs/decomposedfs.go
generated
vendored
@@ -882,6 +882,9 @@ func (fs *Decomposedfs) Download(ctx context.Context, ref *provider.Reference, o
|
||||
if openReaderFunc(ri) {
|
||||
reader, err = fs.tp.ReadBlob(n)
|
||||
if err != nil {
|
||||
if _, ok := err.(errtypes.IsNotFound); ok {
|
||||
return nil, nil, err
|
||||
}
|
||||
return nil, nil, errors.Wrap(err, "Decomposedfs: error download blob '"+n.ID+"'")
|
||||
}
|
||||
}
|
||||
|
||||
3
vendor/github.com/owncloud/reva/v2/pkg/storage/utils/decomposedfs/revisions.go
generated
vendored
3
vendor/github.com/owncloud/reva/v2/pkg/storage/utils/decomposedfs/revisions.go
generated
vendored
@@ -183,6 +183,9 @@ func (fs *Decomposedfs) DownloadRevision(ctx context.Context, ref *provider.Refe
|
||||
if openReaderFunc(ri) {
|
||||
reader, err = fs.tp.ReadBlob(&revisionNode)
|
||||
if err != nil {
|
||||
if _, ok := err.(errtypes.IsNotFound); ok {
|
||||
return nil, nil, err
|
||||
}
|
||||
return nil, nil, errors.Wrapf(err, "Decomposedfs: could not download blob of revision '%s' for node '%s'", n.ID, revisionKey)
|
||||
}
|
||||
}
|
||||
|
||||
2
vendor/modules.txt
vendored
2
vendor/modules.txt
vendored
@@ -1321,7 +1321,7 @@ github.com/orcaman/concurrent-map
|
||||
# github.com/owncloud/libre-graph-api-go v1.0.5-0.20260216101009-eeac018af245
|
||||
## explicit; go 1.18
|
||||
github.com/owncloud/libre-graph-api-go
|
||||
# github.com/owncloud/reva/v2 v2.0.0-20261012083840-8b649a4c3899
|
||||
# github.com/owncloud/reva/v2 v2.0.0-20261013125910-ed54ed63ad22
|
||||
## explicit; go 1.26.0
|
||||
github.com/owncloud/reva/v2/cmd/revad/internal/grace
|
||||
github.com/owncloud/reva/v2/cmd/revad/runtime
|
||||
|
||||
Reference in New Issue
Block a user