diff --git a/cache2go/cache.go b/cache2go/cache.go index 1560c8e51..03b79b647 100644 --- a/cache2go/cache.go +++ b/cache2go/cache.go @@ -20,13 +20,19 @@ type XEntry struct { key string keepAlive bool expireDuration time.Duration + timestamp time.Time t *time.Timer } +type timestampedValue struct { + timestamp time.Time + value interface{} +} + var ( xcache = make(map[string]expiringCacheEntry) xMux sync.RWMutex - cache = make(map[string]interface{}) + cache = make(map[string]timestampedValue) mux sync.RWMutex ) @@ -35,6 +41,7 @@ func (xe *XEntry) XCache(key string, expire time.Duration, value expiringCacheEn xe.keepAlive = true xe.key = key xe.expireDuration = expire + xe.timestamp = time.Now() xMux.Lock() xcache[key] = value xMux.Unlock() @@ -84,7 +91,7 @@ func GetXCached(key string) (ece expiringCacheEntry, err error) { func Cache(key string, value interface{}) { mux.Lock() defer mux.Unlock() - cache[key] = value + cache[key] = timestampedValue{time.Now(), value} } // The function to extract a value for a key that never expire @@ -92,7 +99,7 @@ func GetCached(key string) (v interface{}, err error) { mux.RLock() defer mux.RUnlock() if r, ok := cache[key]; ok { - return r, nil + return r.value, nil } return nil, errors.New("not found") } @@ -113,5 +120,5 @@ func XFlush() { func Flush() { mux.Lock() defer mux.Unlock() - cache = make(map[string]interface{}) + cache = make(map[string]timestampedValue) } diff --git a/engine/destinations.go b/engine/destinations.go index 6b638ae44..7ecdf9f70 100644 --- a/engine/destinations.go +++ b/engine/destinations.go @@ -19,7 +19,6 @@ along with this program. If not, see package engine import ( - "github.com/cgrates/cgrates/cache2go" "strings" ) @@ -31,20 +30,6 @@ type Destination struct { Prefixes []string } -// Gets the specified destination from the storage and caches it. -func GetDestination(dId string) (d *Destination, err error) { - x, err := cache2go.GetCached(dId) - if err != nil { - d, err = storageGetter.GetDestination(dId) - if err == nil && d != nil { - cache2go.Cache(dId, d) - } - } else { - d = x.(*Destination) - } - return -} - func (d *Destination) containsPrefix(prefix string) (precision int, ok bool) { if d == nil { return diff --git a/engine/destinations_test.go b/engine/destinations_test.go index 4602a6585..90b7ebc14 100644 --- a/engine/destinations_test.go +++ b/engine/destinations_test.go @@ -74,28 +74,28 @@ func TestDestinationContainsPrefixWrong(t *testing.T) { } func TestDestinationGetExists(t *testing.T) { - d, err := GetDestination("NAT") + d, err := storageGetter.GetDestination("NAT") if err != nil || d == nil { t.Error("Could not get destination: ", d) } } func TestDestinationGetExistsCache(t *testing.T) { - GetDestination("NAT") + storageGetter.GetDestination("NAT") if _, err := cache2go.GetCached("NAT"); err != nil { - t.Error("Destination not cached!") + t.Error("Destination not cached:", err) } } func TestDestinationGetNotExists(t *testing.T) { - d, err := GetDestination("not existing") + d, err := storageGetter.GetDestination("not existing") if d != nil { t.Error("Got false destination: ", d, err) } } func TestDestinationGetNotExistsCache(t *testing.T) { - GetDestination("not existing") + storageGetter.GetDestination("not existing") if d, err := cache2go.GetCached("not existing"); err == nil { t.Error("Bad destination cached: ", d) } diff --git a/engine/ratingprofile.go b/engine/ratingprofile.go index f37da65d8..c5b45863c 100644 --- a/engine/ratingprofile.go +++ b/engine/ratingprofile.go @@ -21,7 +21,6 @@ package engine import ( "errors" "fmt" - "github.com/cgrates/cgrates/cache2go" "sort" "time" ) @@ -39,18 +38,6 @@ type RatingPlanActivation struct { RatingPlanId string } -func (rpa *RatingPlanActivation) GetRatingPlan() (rp *RatingPlan, err error) { - if x, err := cache2go.GetCached(rpa.RatingPlanId); err != nil { - rp, err = storageGetter.GetRatingPlan(rpa.RatingPlanId) - if err == nil && rp != nil { - cache2go.Cache(rpa.RatingPlanId, rp) - } - } else { - rp = x.(*RatingPlan) - } - return -} - func (rpa *RatingPlanActivation) Equal(orpa *RatingPlanActivation) bool { return rpa.ActivationTime == orpa.ActivationTime && rpa.RatingPlanId == orpa.RatingPlanId } @@ -82,7 +69,7 @@ func (rp *RatingProfile) GetRatingPlansForPrefix(cd *CallDescriptor) (foundPrefi rp.RatingPlanActivations.Sort() for _, rpa := range rp.RatingPlanActivations { if rpa.ActivationTime.Before(cd.TimeEnd) { - rpl, err := rpa.GetRatingPlan() + rpl, err := storageGetter.GetRatingPlan(rpa.RatingPlanId) if err != nil || rpl == nil { Logger.Err(fmt.Sprintf("Error checking destination: %v", err)) continue diff --git a/engine/storage_map.go b/engine/storage_map.go index e342b27c5..830d6bc33 100644 --- a/engine/storage_map.go +++ b/engine/storage_map.go @@ -21,6 +21,7 @@ package engine import ( "errors" "fmt" + "github.com/cgrates/cgrates/cache2go" "github.com/cgrates/cgrates/history" "github.com/cgrates/cgrates/utils" "strings" @@ -44,10 +45,14 @@ func (ms *MapStorage) Flush() error { } func (ms *MapStorage) GetRatingPlan(key string) (rp *RatingPlan, err error) { + if x, err := cache2go.GetCached(key); err == nil { + return x.(*RatingPlan), nil + } if values, ok := ms.dict[RATING_PLAN_PREFIX+key]; ok { rp = new(RatingPlan) err = ms.ms.Unmarshal(values, rp) + cache2go.Cache(key, rp) } else { return nil, errors.New("not found") } @@ -82,9 +87,13 @@ func (ms *MapStorage) SetRatingProfile(rp *RatingProfile) (err error) { } func (ms *MapStorage) GetDestination(key string) (dest *Destination, err error) { + if x, err := cache2go.GetCached(key); err == nil { + return x.(*Destination), nil + } if values, ok := ms.dict[DESTINATION_PREFIX+key]; ok { dest = &Destination{Id: key} err = ms.ms.Unmarshal(values, dest) + cache2go.Cache(key, dest) } else { return nil, errors.New("not found") } diff --git a/engine/storage_redis.go b/engine/storage_redis.go index 6680cedcb..71db07274 100644 --- a/engine/storage_redis.go +++ b/engine/storage_redis.go @@ -22,6 +22,7 @@ import ( "bytes" "compress/zlib" "fmt" + "github.com/cgrates/cgrates/cache2go" "github.com/cgrates/cgrates/history" "github.com/cgrates/cgrates/utils" "io/ioutil" @@ -81,6 +82,9 @@ func (rs *RedisStorage) Flush() (err error) { func (rs *RedisStorage) GetRatingPlan(key string) (rp *RatingPlan, err error) { var values string + if x, err := cache2go.GetCached(key); err == nil { + return x.(*RatingPlan), nil + } if values, err = rs.db.Get(RATING_PLAN_PREFIX + key); err == nil { rp = new(RatingPlan) b := bytes.NewBufferString(values) @@ -94,6 +98,7 @@ func (rs *RedisStorage) GetRatingPlan(key string) (rp *RatingPlan, err error) { } r.Close() err = rs.ms.Unmarshal(out, rp) + cache2go.Cache(key, rp) } return } @@ -132,9 +137,13 @@ func (rs *RedisStorage) SetRatingProfile(rp *RatingProfile) (err error) { } func (rs *RedisStorage) GetDestination(key string) (dest *Destination, err error) { + if x, err := cache2go.GetCached(key); err == nil { + return x.(*Destination), nil + } var values []string if values, err = rs.db.SMembers(DESTINATION_PREFIX + key); len(values) > 0 && err == nil { dest = &Destination{Id: key, Prefixes: values} + cache2go.Cache(key, dest) } return }