github.com/mdaxf/iac@v0.0.0-20240519030858-58a061660378/framework/cache/random_expired_cache.go (about) 1 // The package is migrated from beego, you can get from following link: 2 // import( 3 // "github.com/beego/beego/v2/client/cache" 4 // ) 5 // Copyright 2023. All Rights Reserved. 6 // 7 // Licensed under the Apache License, Version 2.0 (the "License"); 8 // you may not use this file except in compliance with the License. 9 // You may obtain a copy of the License at 10 // 11 // http://www.apache.org/licenses/LICENSE-2.0 12 // 13 // Unless required by applicable law or agreed to in writing, software 14 // distributed under the License is distributed on an "AS IS" BASIS, 15 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 // See the License for the specific language governing permissions and 17 // limitations under the License. 18 19 package cache 20 21 import ( 22 "context" 23 "math/rand" 24 "sync/atomic" 25 "time" 26 ) 27 28 // RandomExpireCacheOption implement genreate random time offset expired option 29 type RandomExpireCacheOption func(*RandomExpireCache) 30 31 // WithRandomExpireOffsetFunc returns a RandomExpireCacheOption that configures the offset function 32 func WithRandomExpireOffsetFunc(fn func() time.Duration) RandomExpireCacheOption { 33 return func(cache *RandomExpireCache) { 34 cache.offset = fn 35 } 36 } 37 38 // RandomExpireCache prevent cache batch invalidation 39 // Cache random time offset expired 40 type RandomExpireCache struct { 41 Cache 42 offset func() time.Duration 43 } 44 45 // Put random time offset expired 46 func (rec *RandomExpireCache) Put(ctx context.Context, key string, val interface{}, timeout time.Duration) error { 47 timeout += rec.offset() 48 return rec.Cache.Put(ctx, key, val, timeout) 49 } 50 51 // NewRandomExpireCache return random expire cache struct 52 func NewRandomExpireCache(adapter Cache, opts ...RandomExpireCacheOption) Cache { 53 rec := RandomExpireCache{ 54 Cache: adapter, 55 offset: defaultExpiredFunc(), 56 } 57 for _, fn := range opts { 58 fn(&rec) 59 } 60 return &rec 61 } 62 63 // defaultExpiredFunc return a func that used to generate random time offset (range: [3s,8s)) expired 64 func defaultExpiredFunc() func() time.Duration { 65 const size = 5 66 var randTimes [size]time.Duration 67 for i := range randTimes { 68 randTimes[i] = time.Duration(i+3) * time.Second 69 } 70 // shuffle values 71 for i := range randTimes { 72 n := rand.Intn(size) 73 randTimes[i], randTimes[n] = randTimes[n], randTimes[i] 74 } 75 var i uint64 76 return func() time.Duration { 77 return randTimes[atomic.AddUint64(&i, 1)%size] 78 } 79 }