github.com/mdaxf/iac@v0.0.0-20240519030858-58a061660378/framework/cache/read_through.go (about) 1 // The package is migrated from beego, you can get from following link: 2 // import( 3 // 4 // "github.com/beego/beego/v2/client/cache" 5 // 6 // ) 7 // Copyright 2023. All Rights Reserved. 8 // 9 // Licensed under the Apache License, Version 2.0 (the "License"); 10 // you may not use this file except in compliance with the License. 11 // You may obtain a copy of the License at 12 // 13 // http://www.apache.org/licenses/LICENSE-2.0 14 // 15 // Unless required by applicable law or agreed to in writing, software 16 // distributed under the License is distributed on an "AS IS" BASIS, 17 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 // See the License for the specific language governing permissions and 19 // limitations under the License. 20 package cache 21 22 import ( 23 "context" 24 "time" 25 26 "github.com/mdaxf/iac/framework/berror" 27 ) 28 29 // readThroughCache is a decorator 30 // add the read through function to the original Cache function 31 type readThroughCache struct { 32 Cache 33 expiration time.Duration 34 loadFunc func(ctx context.Context, key string) (any, error) 35 } 36 37 // NewReadThroughCache create readThroughCache 38 func NewReadThroughCache(cache Cache, expiration time.Duration, 39 loadFunc func(ctx context.Context, key string) (any, error), 40 ) (Cache, error) { 41 if loadFunc == nil { 42 return nil, berror.Error(InvalidLoadFunc, "loadFunc cannot be nil") 43 } 44 return &readThroughCache{ 45 Cache: cache, 46 expiration: expiration, 47 loadFunc: loadFunc, 48 }, nil 49 } 50 51 // Get will try to call the LoadFunc to load data if the Cache returns value nil or non-nil error. 52 func (c *readThroughCache) Get(ctx context.Context, key string) (any, error) { 53 val, err := c.Cache.Get(ctx, key) 54 if val == nil || err != nil { 55 val, err = c.loadFunc(ctx, key) 56 if err != nil { 57 return nil, berror.Wrap( 58 err, LoadFuncFailed, "cache unable to load data") 59 } 60 err = c.Cache.Put(ctx, key, val, c.expiration) 61 if err != nil { 62 return val, err 63 } 64 } 65 return val, nil 66 }