crawling: Apply lifecycle then decide healing action (#11563)

It is inefficient to decide to heal an object before checking its
lifecycle for expiration or transition. This commit will just reverse
the order of action: evaluate lifecycle and heal only if asked and
lifecycle resulted a NoneAction.
This commit is contained in:
Anis Elleuch 2021-03-31 10:15:08 +01:00 committed by GitHub
parent 3ddd8b04d1
commit 6b484f45c6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -814,16 +814,7 @@ type actionMeta struct {
var applyActionsLogPrefix = color.Green("applyActions:") var applyActionsLogPrefix = color.Green("applyActions:")
// applyActions will apply lifecycle checks on to a scanned item. func (i *scannerItem) applyHealing(ctx context.Context, o ObjectLayer, meta actionMeta) (size int64) {
// The resulting size on disk will always be returned.
// The metadata will be compared to consensus on the object layer before any changes are applied.
// If no metadata is supplied, -1 is returned if no action is taken.
func (i *scannerItem) applyActions(ctx context.Context, o ObjectLayer, meta actionMeta) (size int64) {
size, err := meta.oi.GetActualSize()
if i.debug {
logger.LogIf(ctx, err)
}
if i.heal {
if i.debug { if i.debug {
if meta.oi.VersionID != "" { if meta.oi.VersionID != "" {
console.Debugf(applyActionsLogPrefix+" heal checking: %v/%v v(%s)\n", i.bucket, i.objectPath(), meta.oi.VersionID) console.Debugf(applyActionsLogPrefix+" heal checking: %v/%v v(%s)\n", i.bucket, i.objectPath(), meta.oi.VersionID)
@ -843,13 +834,19 @@ func (i *scannerItem) applyActions(ctx context.Context, o ObjectLayer, meta acti
logger.LogIf(ctx, err) logger.LogIf(ctx, err)
return 0 return 0
} }
size = res.ObjectSize return res.ObjectSize
}
func (i *scannerItem) applyLifecycle(ctx context.Context, o ObjectLayer, meta actionMeta) (applied bool, size int64) {
size, err := meta.oi.GetActualSize()
if i.debug {
logger.LogIf(ctx, err)
} }
if i.lifeCycle == nil { if i.lifeCycle == nil {
if i.debug { if i.debug {
console.Debugf(applyActionsLogPrefix+" no lifecycle rules to apply: %q\n", i.objectPath()) console.Debugf(applyActionsLogPrefix+" no lifecycle rules to apply: %q\n", i.objectPath())
} }
return size return false, size
} }
versionID := meta.oi.VersionID versionID := meta.oi.VersionID
@ -883,7 +880,7 @@ func (i *scannerItem) applyActions(ctx context.Context, o ObjectLayer, meta acti
if i.debug { if i.debug {
console.Debugf(applyActionsLogPrefix+" object not expirable: %q\n", i.objectPath()) console.Debugf(applyActionsLogPrefix+" object not expirable: %q\n", i.objectPath())
} }
return size return false, size
} }
obj, err := o.GetObjectInfo(ctx, i.bucket, i.objectPath(), ObjectOptions{ obj, err := o.GetObjectInfo(ctx, i.bucket, i.objectPath(), ObjectOptions{
@ -895,19 +892,18 @@ func (i *scannerItem) applyActions(ctx context.Context, o ObjectLayer, meta acti
if !obj.DeleteMarker { // if this is not a delete marker log and return if !obj.DeleteMarker { // if this is not a delete marker log and return
// Do nothing - heal in the future. // Do nothing - heal in the future.
logger.LogIf(ctx, err) logger.LogIf(ctx, err)
return size return false, size
} }
case ObjectNotFound, VersionNotFound: case ObjectNotFound, VersionNotFound:
// object not found or version not found return 0 // object not found or version not found return 0
return 0 return false, 0
default: default:
// All other errors proceed. // All other errors proceed.
logger.LogIf(ctx, err) logger.LogIf(ctx, err)
return size return false, size
} }
} }
var applied bool
action = evalActionFromLifecycle(ctx, *i.lifeCycle, obj, i.debug) action = evalActionFromLifecycle(ctx, *i.lifeCycle, obj, i.debug)
if action != lifecycle.NoneAction { if action != lifecycle.NoneAction {
applied = applyLifecycleAction(ctx, action, o, obj) applied = applyLifecycleAction(ctx, action, o, obj)
@ -916,9 +912,26 @@ func (i *scannerItem) applyActions(ctx context.Context, o ObjectLayer, meta acti
if applied { if applied {
switch action { switch action {
case lifecycle.TransitionAction, lifecycle.TransitionVersionAction: case lifecycle.TransitionAction, lifecycle.TransitionVersionAction:
default: // for all lifecycle actions that remove data return true, size
return 0
} }
// For all other lifecycle actions that remove data
return true, 0
}
return false, size
}
// applyActions will apply lifecycle checks on to a scanned item.
// The resulting size on disk will always be returned.
// The metadata will be compared to consensus on the object layer before any changes are applied.
// If no metadata is supplied, -1 is returned if no action is taken.
func (i *scannerItem) applyActions(ctx context.Context, o ObjectLayer, meta actionMeta) int64 {
applied, size := i.applyLifecycle(ctx, o, meta)
// For instance, an applied lifecycle means we remove/transitioned an object
// from the current deployment, which means we don't have to call healing
// routine even if we are asked to do via heal flag.
if !applied && i.heal {
size = i.applyHealing(ctx, o, meta)
} }
return size return size
} }