| OLD | NEW |
| 1 // Copyright 2016 The LUCI Authors. All rights reserved. | 1 // Copyright 2016 The LUCI Authors. All rights reserved. |
| 2 // Use of this source code is governed under the Apache License, Version 2.0 | 2 // Use of this source code is governed under the Apache License, Version 2.0 |
| 3 // that can be found in the LICENSE file. | 3 // that can be found in the LICENSE file. |
| 4 | 4 |
| 5 package datastorecache | 5 package datastorecache |
| 6 | 6 |
| 7 import ( | 7 import ( |
| 8 "math" | 8 "math" |
| 9 "time" | 9 "time" |
| 10 | 10 |
| 11 "github.com/luci/luci-go/common/clock" | 11 "github.com/luci/luci-go/common/clock" |
| 12 "github.com/luci/luci-go/common/data/rand/mathrand" | 12 "github.com/luci/luci-go/common/data/rand/mathrand" |
| 13 "github.com/luci/luci-go/common/errors" | 13 "github.com/luci/luci-go/common/errors" |
| 14 log "github.com/luci/luci-go/common/logging" | 14 log "github.com/luci/luci-go/common/logging" |
| 15 "github.com/luci/luci-go/common/retry" | 15 "github.com/luci/luci-go/common/retry" |
| 16 "github.com/luci/luci-go/common/retry/transient" |
| 16 "github.com/luci/luci-go/server/router" | 17 "github.com/luci/luci-go/server/router" |
| 17 | 18 |
| 18 "github.com/luci/gae/impl/prod/constraints" | 19 "github.com/luci/gae/impl/prod/constraints" |
| 19 "github.com/luci/gae/service/datastore" | 20 "github.com/luci/gae/service/datastore" |
| 20 "github.com/luci/gae/service/info" | 21 "github.com/luci/gae/service/info" |
| 21 | 22 |
| 22 "golang.org/x/net/context" | 23 "golang.org/x/net/context" |
| 23 ) | 24 ) |
| 24 | 25 |
| 25 const ( | 26 const ( |
| (...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 289 // We'll try a few times, sleeping a short time in between if we fail to
get | 290 // We'll try a few times, sleeping a short time in between if we fail to
get |
| 290 // the lock. We don't want to wait too long and stall our parent applica
tion, | 291 // the lock. We don't want to wait too long and stall our parent applica
tion, |
| 291 // though. | 292 // though. |
| 292 var ( | 293 var ( |
| 293 attempts = 0 | 294 attempts = 0 |
| 294 acquiredLock = false | 295 acquiredLock = false |
| 295 refreshValue Value | 296 refreshValue Value |
| 296 delta time.Duration | 297 delta time.Duration |
| 297 ) | 298 ) |
| 298 err := retry.Retry(clock.Tag(c, "datastoreCacheLockRetry"), | 299 err := retry.Retry(clock.Tag(c, "datastoreCacheLockRetry"), |
| 299 » » retry.TransientOnly(bci.refreshRetryFactory), func() error { | 300 » » transient.Only(bci.refreshRetryFactory), func() error { |
| 300 | 301 |
| 301 // This is a retry. If the entry was missing before, che
ck to see if some | 302 // This is a retry. If the entry was missing before, che
ck to see if some |
| 302 // other process has since added it to the datastore. | 303 // other process has since added it to the datastore. |
| 303 // We only check this on the 2+ retry because we already
checked this | 304 // We only check this on the 2+ retry because we already
checked this |
| 304 // condition above in the initial datastore Get. | 305 // condition above in the initial datastore Get. |
| 305 // | 306 // |
| 306 // If this fails, we'll continue to try and perform the
Refresh. | 307 // If this fails, we'll continue to try and perform the
Refresh. |
| 307 if entryWasMissing && attempts > 0 { | 308 if entryWasMissing && attempts > 0 { |
| 308 switch err := datastore.Get(c, &e); err { | 309 switch err := datastore.Get(c, &e); err { |
| 309 case nil: | 310 case nil: |
| (...skipping 19 matching lines...) Expand all Loading... |
| 329 refreshValue, delta, err = doRefresh(c, bci.h, &
e, userNS) | 330 refreshValue, delta, err = doRefresh(c, bci.h, &
e, userNS) |
| 330 return | 331 return |
| 331 }) | 332 }) |
| 332 switch err { | 333 switch err { |
| 333 case nil: | 334 case nil: |
| 334 // Successfully loaded. | 335 // Successfully loaded. |
| 335 return nil | 336 return nil |
| 336 | 337 |
| 337 case ErrFailedToLock: | 338 case ErrFailedToLock: |
| 338 // Retry after delay. | 339 // Retry after delay. |
| 339 » » » » return errors.WrapTransient(err) | 340 » » » » return transient.Tag.Apply(err) |
| 340 | 341 |
| 341 default: | 342 default: |
| 342 log.WithError(err).Warningf(c, "Unexpected failu
re obtaining initial load lock.") | 343 log.WithError(err).Warningf(c, "Unexpected failu
re obtaining initial load lock.") |
| 343 return err | 344 return err |
| 344 } | 345 } |
| 345 }, func(err error, d time.Duration) { | 346 }, func(err error, d time.Duration) { |
| 346 log.WithError(err).Debugf(c, "Failed to acquire initial
refresh lock. Retrying...") | 347 log.WithError(err).Debugf(c, "Failed to acquire initial
refresh lock. Retrying...") |
| 347 }) | 348 }) |
| 348 if err != nil { | 349 if err != nil { |
| 349 // If we actually acquired the lock, then this refresh was a fai
lure, and | 350 // If we actually acquired the lock, then this refresh was a fai
lure, and |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 455 // delta is a factor representing the amount of time that it takes to | 456 // delta is a factor representing the amount of time that it takes to |
| 456 // recalculate the value. Higher delta values allow for earlier recomputation | 457 // recalculate the value. Higher delta values allow for earlier recomputation |
| 457 // for values that take longer to calculate. | 458 // for values that take longer to calculate. |
| 458 // | 459 // |
| 459 // beta can be set to >1 to favor earlier recomputations; however, in practice | 460 // beta can be set to >1 to favor earlier recomputations; however, in practice |
| 460 // beta=1 works well. | 461 // beta=1 works well. |
| 461 func xFetch(now, expiry time.Time, delta time.Duration, beta float64, rf randFun
c) bool { | 462 func xFetch(now, expiry time.Time, delta time.Duration, beta float64, rf randFun
c) bool { |
| 462 offset := time.Duration(float64(delta) * beta * math.Log(rf())) | 463 offset := time.Duration(float64(delta) * beta * math.Log(rf())) |
| 463 return !now.Add(-offset).Before(expiry) | 464 return !now.Add(-offset).Before(expiry) |
| 464 } | 465 } |
| OLD | NEW |