From 5ebfa319fc33a776fa5ebd9e25c0d6c20620bf60 Mon Sep 17 00:00:00 2001 From: Radu Ioan Fericean Date: Sun, 8 Nov 2015 16:26:57 +0200 Subject: [PATCH] cache action plans fixes #279, fixes #281 --- apier/v1/accounts.go | 4 +-- apier/v1/apier.go | 1 + engine/calldesc_test.go | 36 ++++++++++---------- engine/storage_interface.go | 2 +- engine/storage_map.go | 50 ++++++++++++++++++++-------- engine/storage_mongo.go | 65 ++++++++++++++++++++++++++++++------- engine/storage_redis.go | 63 ++++++++++++++++++++++++++--------- engine/tp_reader.go | 2 +- scheduler/scheduler.go | 1 + 9 files changed, 160 insertions(+), 64 deletions(-) diff --git a/apier/v1/accounts.go b/apier/v1/accounts.go index c79c11ee8..d6ca55be5 100644 --- a/apier/v1/accounts.go +++ b/apier/v1/accounts.go @@ -82,7 +82,7 @@ func (self *ApierV1) RemActionTiming(attrs AttrRemActionTiming, reply *string) e } } _, err := engine.Guardian.Guard(func() (interface{}, error) { - ats, err := self.RatingDb.GetActionPlans(attrs.ActionPlanId) + ats, err := self.RatingDb.GetActionPlans(attrs.ActionPlanId, false) if err != nil { return 0, err } else if len(ats) == 0 { @@ -175,7 +175,7 @@ func (self *ApierV1) SetAccount(attr utils.AttrSetAccount, reply *string) error if len(attr.ActionPlanId) != 0 { var err error - ats, err = self.RatingDb.GetActionPlans(attr.ActionPlanId) + ats, err = self.RatingDb.GetActionPlans(attr.ActionPlanId, false) if err != nil { return 0, err } diff --git a/apier/v1/apier.go b/apier/v1/apier.go index 0e2240d10..e87a518ff 100644 --- a/apier/v1/apier.go +++ b/apier/v1/apier.go @@ -712,6 +712,7 @@ func (self *ApierV1) SetActionPlan(attrs AttrSetActionPlan, reply *string) error if err := self.RatingDb.SetActionPlans(attrs.Id, storeAtms); err != nil { return utils.NewErrServerError(err) } + self.RatingDb.CacheRatingPrefixValues(map[string][]string{utils.ACTION_PLAN_PREFIX: []string{attrs.Id}}) if attrs.ReloadScheduler { if self.Sched == nil { return errors.New("SCHEDULER_NOT_ENABLED") diff --git a/engine/calldesc_test.go b/engine/calldesc_test.go index 8d540d6f9..3fa4d287a 100644 --- a/engine/calldesc_test.go +++ b/engine/calldesc_test.go @@ -487,7 +487,7 @@ func TestMaxSessionTimeWithAccount(t *testing.T) { } func TestMaxSessionTimeWithMaxRate(t *testing.T) { - ap, _ := ratingStorage.GetActionPlans("TOPUP10_AT") + ap, _ := ratingStorage.GetActionPlans("TOPUP10_AT", false) for _, at := range ap { at.Execute() } @@ -513,7 +513,7 @@ func TestMaxSessionTimeWithMaxRate(t *testing.T) { } func TestMaxSessionTimeWithMaxCost(t *testing.T) { - ap, _ := ratingStorage.GetActionPlans("TOPUP10_AT") + ap, _ := ratingStorage.GetActionPlans("TOPUP10_AT", false) for _, at := range ap { at.Execute() } @@ -536,7 +536,7 @@ func TestMaxSessionTimeWithMaxCost(t *testing.T) { } func TestGetCostWithMaxCost(t *testing.T) { - ap, _ := ratingStorage.GetActionPlans("TOPUP10_AT") + ap, _ := ratingStorage.GetActionPlans("TOPUP10_AT", false) for _, at := range ap { at.Execute() } @@ -558,7 +558,7 @@ func TestGetCostWithMaxCost(t *testing.T) { } } func TestGetCostRoundingIssue(t *testing.T) { - ap, _ := ratingStorage.GetActionPlans("TOPUP10_AT") + ap, _ := ratingStorage.GetActionPlans("TOPUP10_AT", false) for _, at := range ap { at.Execute() } @@ -582,7 +582,7 @@ func TestGetCostRoundingIssue(t *testing.T) { } func TestGetCostMaxDebitRoundingIssue(t *testing.T) { - ap, _ := ratingStorage.GetActionPlans("TOPUP10_AT") + ap, _ := ratingStorage.GetActionPlans("TOPUP10_AT", false) for _, at := range ap { at.Execute() } @@ -614,7 +614,7 @@ func TestGetCostMaxDebitRoundingIssue(t *testing.T) { } func TestMaxSessionTimeWithMaxCostFree(t *testing.T) { - ap, _ := ratingStorage.GetActionPlans("TOPUP10_AT") + ap, _ := ratingStorage.GetActionPlans("TOPUP10_AT", false) for _, at := range ap { at.Execute() } @@ -637,7 +637,7 @@ func TestMaxSessionTimeWithMaxCostFree(t *testing.T) { } func TestMaxDebitWithMaxCostFree(t *testing.T) { - ap, _ := ratingStorage.GetActionPlans("TOPUP10_AT") + ap, _ := ratingStorage.GetActionPlans("TOPUP10_AT", false) for _, at := range ap { at.Execute() } @@ -660,7 +660,7 @@ func TestMaxDebitWithMaxCostFree(t *testing.T) { } func TestGetCostWithMaxCostFree(t *testing.T) { - ap, _ := ratingStorage.GetActionPlans("TOPUP10_AT") + ap, _ := ratingStorage.GetActionPlans("TOPUP10_AT", false) for _, at := range ap { at.Execute() } @@ -714,11 +714,11 @@ func TestMaxSessionTimeWithAccountAlias(t *testing.T) { } func TestMaxSessionTimeWithAccountShared(t *testing.T) { - ap, _ := ratingStorage.GetActionPlans("TOPUP_SHARED0_AT") + ap, _ := ratingStorage.GetActionPlans("TOPUP_SHARED0_AT", false) for _, at := range ap { at.Execute() } - ap, _ = ratingStorage.GetActionPlans("TOPUP_SHARED10_AT") + ap, _ = ratingStorage.GetActionPlans("TOPUP_SHARED10_AT", false) for _, at := range ap { at.Execute() } @@ -753,11 +753,11 @@ func TestMaxSessionTimeWithAccountShared(t *testing.T) { } func TestMaxDebitWithAccountShared(t *testing.T) { - ap, _ := ratingStorage.GetActionPlans("TOPUP_SHARED0_AT") + ap, _ := ratingStorage.GetActionPlans("TOPUP_SHARED0_AT", false) for _, at := range ap { at.Execute() } - ap, _ = ratingStorage.GetActionPlans("TOPUP_SHARED10_AT") + ap, _ = ratingStorage.GetActionPlans("TOPUP_SHARED10_AT", false) for _, at := range ap { at.Execute() } @@ -974,7 +974,7 @@ func TestMaxSesionTimeLongerThanMoney(t *testing.T) { } func TestDebitFromShareAndNormal(t *testing.T) { - ap, _ := ratingStorage.GetActionPlans("TOPUP_SHARED10_AT") + ap, _ := ratingStorage.GetActionPlans("TOPUP_SHARED10_AT", false) for _, at := range ap { at.Execute() } @@ -1002,7 +1002,7 @@ func TestDebitFromShareAndNormal(t *testing.T) { } func TestDebitFromEmptyShare(t *testing.T) { - ap, _ := ratingStorage.GetActionPlans("TOPUP_EMPTY_AT") + ap, _ := ratingStorage.GetActionPlans("TOPUP_EMPTY_AT", false) for _, at := range ap { at.Execute() } @@ -1030,7 +1030,7 @@ func TestDebitFromEmptyShare(t *testing.T) { } func TestDebitNegatve(t *testing.T) { - ap, _ := ratingStorage.GetActionPlans("POST_AT") + ap, _ := ratingStorage.GetActionPlans("POST_AT", false) for _, at := range ap { at.Execute() } @@ -1069,7 +1069,7 @@ func TestDebitNegatve(t *testing.T) { } func TestMaxDebitZeroDefinedRate(t *testing.T) { - ap, _ := ratingStorage.GetActionPlans("TOPUP10_AT") + ap, _ := ratingStorage.GetActionPlans("TOPUP10_AT", false) for _, at := range ap { at.Execute() } @@ -1097,7 +1097,7 @@ func TestMaxDebitZeroDefinedRate(t *testing.T) { } func TestMaxDebitZeroDefinedRateOnlyMinutes(t *testing.T) { - ap, _ := ratingStorage.GetActionPlans("TOPUP10_AT") + ap, _ := ratingStorage.GetActionPlans("TOPUP10_AT", false) for _, at := range ap { at.Execute() } @@ -1125,7 +1125,7 @@ func TestMaxDebitZeroDefinedRateOnlyMinutes(t *testing.T) { } func TestMaxDebitConsumesMinutes(t *testing.T) { - ap, _ := ratingStorage.GetActionPlans("TOPUP10_AT") + ap, _ := ratingStorage.GetActionPlans("TOPUP10_AT", false) for _, at := range ap { at.Execute() } diff --git a/engine/storage_interface.go b/engine/storage_interface.go index f18a652f3..1490cdcbd 100644 --- a/engine/storage_interface.go +++ b/engine/storage_interface.go @@ -63,7 +63,7 @@ type RatingStorage interface { SetSharedGroup(*SharedGroup) error GetActionTriggers(string) (ActionTriggers, error) SetActionTriggers(string, ActionTriggers) error - GetActionPlans(string) (ActionPlans, error) + GetActionPlans(string, bool) (ActionPlans, error) SetActionPlans(string, ActionPlans) error GetAllActionPlans() (map[string]ActionPlans, error) } diff --git a/engine/storage_map.go b/engine/storage_map.go index da13aec99..772cfa2ba 100644 --- a/engine/storage_map.go +++ b/engine/storage_map.go @@ -63,7 +63,7 @@ func (ms *MapStorage) GetKeysForPrefix(prefix string) ([]string, error) { } func (ms *MapStorage) CacheRatingAll() error { - return ms.cacheRating(nil, nil, nil, nil, nil, nil, nil) + return ms.cacheRating(nil, nil, nil, nil, nil, nil, nil, nil) } func (ms *MapStorage) CacheRatingPrefixes(prefixes ...string) error { @@ -74,6 +74,7 @@ func (ms *MapStorage) CacheRatingPrefixes(prefixes ...string) error { utils.LCR_PREFIX: []string{}, utils.DERIVEDCHARGERS_PREFIX: []string{}, utils.ACTION_PREFIX: []string{}, + utils.ACTION_PLAN_PREFIX: []string{}, utils.SHARED_GROUP_PREFIX: []string{}, } for _, prefix := range prefixes { @@ -82,7 +83,7 @@ func (ms *MapStorage) CacheRatingPrefixes(prefixes ...string) error { } pm[prefix] = nil } - return ms.cacheRating(pm[utils.DESTINATION_PREFIX], pm[utils.RATING_PLAN_PREFIX], pm[utils.RATING_PROFILE_PREFIX], pm[utils.LCR_PREFIX], pm[utils.DERIVEDCHARGERS_PREFIX], pm[utils.ACTION_PREFIX], pm[utils.SHARED_GROUP_PREFIX]) + return ms.cacheRating(pm[utils.DESTINATION_PREFIX], pm[utils.RATING_PLAN_PREFIX], pm[utils.RATING_PROFILE_PREFIX], pm[utils.LCR_PREFIX], pm[utils.DERIVEDCHARGERS_PREFIX], pm[utils.ACTION_PREFIX], pm[utils.ACTION_PLAN_PREFIX], pm[utils.SHARED_GROUP_PREFIX]) } func (ms *MapStorage) CacheRatingPrefixValues(prefixes map[string][]string) error { @@ -93,6 +94,7 @@ func (ms *MapStorage) CacheRatingPrefixValues(prefixes map[string][]string) erro utils.LCR_PREFIX: []string{}, utils.DERIVEDCHARGERS_PREFIX: []string{}, utils.ACTION_PREFIX: []string{}, + utils.ACTION_PLAN_PREFIX: []string{}, utils.SHARED_GROUP_PREFIX: []string{}, } for prefix, ids := range prefixes { @@ -101,10 +103,10 @@ func (ms *MapStorage) CacheRatingPrefixValues(prefixes map[string][]string) erro } pm[prefix] = ids } - return ms.cacheRating(pm[utils.DESTINATION_PREFIX], pm[utils.RATING_PLAN_PREFIX], pm[utils.RATING_PROFILE_PREFIX], pm[utils.LCR_PREFIX], pm[utils.DERIVEDCHARGERS_PREFIX], pm[utils.ACTION_PREFIX], pm[utils.SHARED_GROUP_PREFIX]) + return ms.cacheRating(pm[utils.DESTINATION_PREFIX], pm[utils.RATING_PLAN_PREFIX], pm[utils.RATING_PROFILE_PREFIX], pm[utils.LCR_PREFIX], pm[utils.DERIVEDCHARGERS_PREFIX], pm[utils.ACTION_PREFIX], pm[utils.ACTION_PLAN_PREFIX], pm[utils.SHARED_GROUP_PREFIX]) } -func (ms *MapStorage) cacheRating(dKeys, rpKeys, rpfKeys, lcrKeys, dcsKeys, actKeys, shgKeys []string) error { +func (ms *MapStorage) cacheRating(dKeys, rpKeys, rpfKeys, lcrKeys, dcsKeys, actKeys, aplKeys, shgKeys []string) error { cache2go.BeginTransaction() if dKeys == nil || (float64(cache2go.CountEntries(utils.DESTINATION_PREFIX))*utils.DESTINATIONS_LOAD_THRESHOLD < float64(len(dKeys))) { cache2go.RemPrefixKey(utils.DESTINATION_PREFIX) @@ -126,6 +128,9 @@ func (ms *MapStorage) cacheRating(dKeys, rpKeys, rpfKeys, lcrKeys, dcsKeys, actK if actKeys == nil { cache2go.RemPrefixKey(utils.ACTION_PREFIX) // Forced until we can fine tune it } + if aplKeys == nil { + cache2go.RemPrefixKey(utils.ACTION_PLAN_PREFIX) + } if shgKeys == nil { cache2go.RemPrefixKey(utils.SHARED_GROUP_PREFIX) // Forced until we can fine tune it } @@ -171,6 +176,13 @@ func (ms *MapStorage) cacheRating(dKeys, rpKeys, rpfKeys, lcrKeys, dcsKeys, actK return err } } + if strings.HasPrefix(k, utils.ACTION_PLAN_PREFIX) { + cache2go.RemKey(k) + if _, err := ms.GetActionPlans(k[len(utils.ACTION_PLAN_PREFIX):], true); err != nil { + cache2go.RollbackTransaction() + return err + } + } if strings.HasPrefix(k, utils.SHARED_GROUP_PREFIX) { cache2go.RemKey(k) if _, err := ms.GetSharedGroup(k[len(utils.SHARED_GROUP_PREFIX):], true); err != nil { @@ -665,9 +677,18 @@ func (ms *MapStorage) SetActionTriggers(key string, atrs ActionTriggers) (err er return } -func (ms *MapStorage) GetActionPlans(key string) (ats ActionPlans, err error) { - if values, ok := ms.dict[utils.ACTION_PLAN_PREFIX+key]; ok { +func (ms *MapStorage) GetActionPlans(key string, skipCache bool) (ats ActionPlans, err error) { + key = utils.ACTION_PLAN_PREFIX + key + if !skipCache { + if x, err := cache2go.Get(key); err == nil { + return x.(ActionPlans), nil + } else { + return nil, err + } + } + if values, ok := ms.dict[key]; ok { err = ms.ms.Unmarshal(values, &ats) + cache2go.Cache(key, ats) } else { return nil, utils.ErrNotFound } @@ -686,14 +707,15 @@ func (ms *MapStorage) SetActionPlans(key string, ats ActionPlans) (err error) { } func (ms *MapStorage) GetAllActionPlans() (ats map[string]ActionPlans, err error) { - ats = make(map[string]ActionPlans) - for key, value := range ms.dict { - if !strings.HasPrefix(key, utils.ACTION_PLAN_PREFIX) { - continue - } - var tempAts ActionPlans - err = ms.ms.Unmarshal(value, &tempAts) - ats[key[len(utils.ACTION_PLAN_PREFIX):]] = tempAts + apls, err := cache2go.GetAllEntries(utils.ACTION_PLAN_PREFIX) + if err != nil { + return nil, err + } + + ats = make(map[string]ActionPlans, len(apls)) + for key, value := range apls { + apl := value.Value().(ActionPlans) + ats[key[len(utils.ACTION_PLAN_PREFIX):]] = apl } return diff --git a/engine/storage_mongo.go b/engine/storage_mongo.go index 3edad9cc9..dcaa9fa2c 100644 --- a/engine/storage_mongo.go +++ b/engine/storage_mongo.go @@ -225,7 +225,7 @@ func (ms *MongoStorage) Flush(ignore string) (err error) { } func (ms *MongoStorage) CacheRatingAll() error { - return ms.cacheRating(nil, nil, nil, nil, nil, nil, nil) + return ms.cacheRating(nil, nil, nil, nil, nil, nil, nil, nil) } func (ms *MongoStorage) CacheRatingPrefixes(prefixes ...string) error { @@ -236,6 +236,7 @@ func (ms *MongoStorage) CacheRatingPrefixes(prefixes ...string) error { utils.LCR_PREFIX: []string{}, utils.DERIVEDCHARGERS_PREFIX: []string{}, utils.ACTION_PREFIX: []string{}, + utils.ACTION_PLAN_PREFIX: []string{}, utils.SHARED_GROUP_PREFIX: []string{}, } for _, prefix := range prefixes { @@ -244,7 +245,7 @@ func (ms *MongoStorage) CacheRatingPrefixes(prefixes ...string) error { } pm[prefix] = nil } - return ms.cacheRating(pm[utils.DESTINATION_PREFIX], pm[utils.RATING_PLAN_PREFIX], pm[utils.RATING_PROFILE_PREFIX], pm[utils.LCR_PREFIX], pm[utils.DERIVEDCHARGERS_PREFIX], pm[utils.ACTION_PREFIX], pm[utils.SHARED_GROUP_PREFIX]) + return ms.cacheRating(pm[utils.DESTINATION_PREFIX], pm[utils.RATING_PLAN_PREFIX], pm[utils.RATING_PROFILE_PREFIX], pm[utils.LCR_PREFIX], pm[utils.DERIVEDCHARGERS_PREFIX], pm[utils.ACTION_PREFIX], pm[utils.ACTION_PLAN_PREFIX], pm[utils.SHARED_GROUP_PREFIX]) } func (ms *MongoStorage) CacheRatingPrefixValues(prefixes map[string][]string) error { @@ -255,6 +256,7 @@ func (ms *MongoStorage) CacheRatingPrefixValues(prefixes map[string][]string) er utils.LCR_PREFIX: []string{}, utils.DERIVEDCHARGERS_PREFIX: []string{}, utils.ACTION_PREFIX: []string{}, + utils.ACTION_PLAN_PREFIX: []string{}, utils.SHARED_GROUP_PREFIX: []string{}, } for prefix, ids := range prefixes { @@ -263,10 +265,10 @@ func (ms *MongoStorage) CacheRatingPrefixValues(prefixes map[string][]string) er } pm[prefix] = ids } - return ms.cacheRating(pm[utils.DESTINATION_PREFIX], pm[utils.RATING_PLAN_PREFIX], pm[utils.RATING_PROFILE_PREFIX], pm[utils.LCR_PREFIX], pm[utils.DERIVEDCHARGERS_PREFIX], pm[utils.ACTION_PREFIX], pm[utils.SHARED_GROUP_PREFIX]) + return ms.cacheRating(pm[utils.DESTINATION_PREFIX], pm[utils.RATING_PLAN_PREFIX], pm[utils.RATING_PROFILE_PREFIX], pm[utils.LCR_PREFIX], pm[utils.DERIVEDCHARGERS_PREFIX], pm[utils.ACTION_PREFIX], pm[utils.ACTION_PLAN_PREFIX], pm[utils.SHARED_GROUP_PREFIX]) } -func (ms *MongoStorage) cacheRating(dKeys, rpKeys, rpfKeys, lcrKeys, dcsKeys, actKeys, shgKeys []string) (err error) { +func (ms *MongoStorage) cacheRating(dKeys, rpKeys, rpfKeys, lcrKeys, dcsKeys, actKeys, aplKeys, shgKeys []string) (err error) { cache2go.BeginTransaction() keyResult := struct{ Key string }{} idResult := struct{ Id string }{} @@ -430,6 +432,35 @@ func (ms *MongoStorage) cacheRating(dKeys, rpKeys, rpfKeys, lcrKeys, dcsKeys, ac utils.Logger.Info("Finished actions caching.") } + if aplKeys == nil { + cache2go.RemPrefixKey(utils.ACTION_PLAN_PREFIX) + } + if aplKeys == nil { + utils.Logger.Info("Caching all action plans") + iter := ms.db.C(colApl).Find(nil).Select(bson.M{"key": 1}).Iter() + aplKeys = make([]string, 0) + for iter.Next(&keyResult) { + aplKeys = append(aplKeys, utils.ACTION_PLAN_PREFIX+keyResult.Key) + } + if err := iter.Close(); err != nil { + cache2go.RollbackTransaction() + return err + } + cache2go.RemPrefixKey(utils.ACTION_PLAN_PREFIX) + } else if len(aplKeys) != 0 { + utils.Logger.Info(fmt.Sprintf("Caching action plans: %v", aplKeys)) + } + for _, key := range aplKeys { + cache2go.RemKey(key) + if _, err = ms.GetActionPlans(key[len(utils.ACTION_PLAN_PREFIX):], true); err != nil { + cache2go.RollbackTransaction() + return err + } + } + if len(aplKeys) != 0 { + utils.Logger.Info("Finished action plans caching.") + } + if shgKeys == nil { cache2go.RemPrefixKey(utils.SHARED_GROUP_PREFIX) } @@ -1025,7 +1056,14 @@ func (ms *MongoStorage) SetActionTriggers(key string, atrs ActionTriggers) (err return err } -func (ms *MongoStorage) GetActionPlans(key string) (ats ActionPlans, err error) { +func (ms *MongoStorage) GetActionPlans(key string, skipCache bool) (ats ActionPlans, err error) { + if !skipCache { + if x, err := cache2go.Get(utils.ACTION_PLAN_PREFIX + key); err == nil { + return x.(ActionPlans), nil + } else { + return nil, err + } + } var kv struct { Key string Value ActionPlans @@ -1033,6 +1071,7 @@ func (ms *MongoStorage) GetActionPlans(key string) (ats ActionPlans, err error) err = ms.db.C(colApl).Find(bson.M{"key": key}).One(&kv) if err == nil { ats = kv.Value + cache2go.Cache(utils.ACTION_PLAN_PREFIX+key, ats) } return } @@ -1046,15 +1085,17 @@ func (ms *MongoStorage) SetActionPlans(key string, ats ActionPlans) error { } func (ms *MongoStorage) GetAllActionPlans() (ats map[string]ActionPlans, err error) { - var kv struct { - Key string - Value ActionPlans + apls, err := cache2go.GetAllEntries(utils.ACTION_PLAN_PREFIX) + if err != nil { + return nil, err } - iter := ms.db.C(colApl).Find(nil).Iter() - ats = make(map[string]ActionPlans) - for iter.Next(&kv) { - ats[kv.Key] = kv.Value + + ats = make(map[string]ActionPlans, len(apls)) + for key, value := range apls { + apl := value.Value().(ActionPlans) + ats[key[len(utils.ACTION_PLAN_PREFIX):]] = apl } + return } diff --git a/engine/storage_redis.go b/engine/storage_redis.go index 72ccbb664..deb383538 100644 --- a/engine/storage_redis.go +++ b/engine/storage_redis.go @@ -68,7 +68,7 @@ func (rs *RedisStorage) GetKeysForPrefix(prefix string) ([]string, error) { } func (rs *RedisStorage) CacheRatingAll() error { - return rs.cacheRating(nil, nil, nil, nil, nil, nil, nil) + return rs.cacheRating(nil, nil, nil, nil, nil, nil, nil, nil) } func (rs *RedisStorage) CacheRatingPrefixes(prefixes ...string) error { @@ -79,6 +79,7 @@ func (rs *RedisStorage) CacheRatingPrefixes(prefixes ...string) error { utils.LCR_PREFIX: []string{}, utils.DERIVEDCHARGERS_PREFIX: []string{}, utils.ACTION_PREFIX: []string{}, + utils.ACTION_PLAN_PREFIX: []string{}, utils.SHARED_GROUP_PREFIX: []string{}, } for _, prefix := range prefixes { @@ -87,7 +88,7 @@ func (rs *RedisStorage) CacheRatingPrefixes(prefixes ...string) error { } pm[prefix] = nil } - return rs.cacheRating(pm[utils.DESTINATION_PREFIX], pm[utils.RATING_PLAN_PREFIX], pm[utils.RATING_PROFILE_PREFIX], pm[utils.LCR_PREFIX], pm[utils.DERIVEDCHARGERS_PREFIX], pm[utils.ACTION_PREFIX], pm[utils.SHARED_GROUP_PREFIX]) + return rs.cacheRating(pm[utils.DESTINATION_PREFIX], pm[utils.RATING_PLAN_PREFIX], pm[utils.RATING_PROFILE_PREFIX], pm[utils.LCR_PREFIX], pm[utils.DERIVEDCHARGERS_PREFIX], pm[utils.ACTION_PREFIX], pm[utils.ACTION_PLAN_PREFIX], pm[utils.SHARED_GROUP_PREFIX]) } func (rs *RedisStorage) CacheRatingPrefixValues(prefixes map[string][]string) error { @@ -98,6 +99,7 @@ func (rs *RedisStorage) CacheRatingPrefixValues(prefixes map[string][]string) er utils.LCR_PREFIX: []string{}, utils.DERIVEDCHARGERS_PREFIX: []string{}, utils.ACTION_PREFIX: []string{}, + utils.ACTION_PLAN_PREFIX: []string{}, utils.SHARED_GROUP_PREFIX: []string{}, } for prefix, ids := range prefixes { @@ -106,10 +108,10 @@ func (rs *RedisStorage) CacheRatingPrefixValues(prefixes map[string][]string) er } pm[prefix] = ids } - return rs.cacheRating(pm[utils.DESTINATION_PREFIX], pm[utils.RATING_PLAN_PREFIX], pm[utils.RATING_PROFILE_PREFIX], pm[utils.LCR_PREFIX], pm[utils.DERIVEDCHARGERS_PREFIX], pm[utils.ACTION_PREFIX], pm[utils.SHARED_GROUP_PREFIX]) + return rs.cacheRating(pm[utils.DESTINATION_PREFIX], pm[utils.RATING_PLAN_PREFIX], pm[utils.RATING_PROFILE_PREFIX], pm[utils.LCR_PREFIX], pm[utils.DERIVEDCHARGERS_PREFIX], pm[utils.ACTION_PREFIX], pm[utils.ACTION_PLAN_PREFIX], pm[utils.SHARED_GROUP_PREFIX]) } -func (rs *RedisStorage) cacheRating(dKeys, rpKeys, rpfKeys, lcrKeys, dcsKeys, actKeys, shgKeys []string) (err error) { +func (rs *RedisStorage) cacheRating(dKeys, rpKeys, rpfKeys, lcrKeys, dcsKeys, actKeys, aplKeys, shgKeys []string) (err error) { cache2go.BeginTransaction() if dKeys == nil || (float64(cache2go.CountEntries(utils.DESTINATION_PREFIX))*utils.DESTINATIONS_LOAD_THRESHOLD < float64(len(dKeys))) { // if need to load more than a half of exiting keys load them all @@ -241,6 +243,30 @@ func (rs *RedisStorage) cacheRating(dKeys, rpKeys, rpfKeys, lcrKeys, dcsKeys, ac utils.Logger.Info("Finished actions caching.") } + if aplKeys == nil { + cache2go.RemPrefixKey(utils.ACTION_PLAN_PREFIX) + } + if aplKeys == nil { + utils.Logger.Info("Caching all action plans") + if aplKeys, err = rs.db.Keys(utils.ACTION_PLAN_PREFIX + "*"); err != nil { + cache2go.RollbackTransaction() + return err + } + cache2go.RemPrefixKey(utils.ACTION_PLAN_PREFIX) + } else if len(aplKeys) != 0 { + utils.Logger.Info(fmt.Sprintf("Caching action plan: %v", aplKeys)) + } + for _, key := range aplKeys { + cache2go.RemKey(key) + if _, err = rs.GetActionPlans(key[len(utils.ACTION_PLAN_PREFIX):], true); err != nil { + cache2go.RollbackTransaction() + return err + } + } + if len(aplKeys) != 0 { + utils.Logger.Info("Finished action plans caching.") + } + if shgKeys == nil { cache2go.RemPrefixKey(utils.SHARED_GROUP_PREFIX) } @@ -826,10 +852,19 @@ func (rs *RedisStorage) SetActionTriggers(key string, atrs ActionTriggers) (err return } -func (rs *RedisStorage) GetActionPlans(key string) (ats ActionPlans, err error) { +func (rs *RedisStorage) GetActionPlans(key string, skipCache bool) (ats ActionPlans, err error) { + key = utils.ACTION_PLAN_PREFIX + key + if !skipCache { + if x, err := cache2go.Get(key); err == nil { + return x.(ActionPlans), nil + } else { + return nil, err + } + } var values []byte - if values, err = rs.db.Get(utils.ACTION_PLAN_PREFIX + key); err == nil { + if values, err = rs.db.Get(key); err == nil { err = rs.ms.Unmarshal(values, &ats) + cache2go.Cache(key, ats) } return } @@ -849,19 +884,15 @@ func (rs *RedisStorage) SetActionPlans(key string, ats ActionPlans) (err error) } func (rs *RedisStorage) GetAllActionPlans() (ats map[string]ActionPlans, err error) { - keys, err := rs.db.Keys(utils.ACTION_PLAN_PREFIX + "*") + apls, err := cache2go.GetAllEntries(utils.ACTION_PLAN_PREFIX) if err != nil { return nil, err } - ats = make(map[string]ActionPlans, len(keys)) - for _, key := range keys { - values, err := rs.db.Get(key) - if err != nil { - continue - } - var tempAts ActionPlans - err = rs.ms.Unmarshal(values, &tempAts) - ats[key[len(utils.ACTION_PLAN_PREFIX):]] = tempAts + + ats = make(map[string]ActionPlans, len(apls)) + for key, value := range apls { + apl := value.Value().(ActionPlans) + ats[key[len(utils.ACTION_PLAN_PREFIX):]] = apl } return diff --git a/engine/tp_reader.go b/engine/tp_reader.go index 6364eb602..72d62d059 100644 --- a/engine/tp_reader.go +++ b/engine/tp_reader.go @@ -652,7 +652,7 @@ func (tpr *TpReader) LoadAccountActionsFiltered(qriedAA *TpAccountAction) error if accountAction.ActionPlanId != "" { // get old userBalanceIds var exitingAccountIds []string - existingActionPlans, err := tpr.ratingStorage.GetActionPlans(accountAction.ActionPlanId) + existingActionPlans, err := tpr.ratingStorage.GetActionPlans(accountAction.ActionPlanId, true) if err == nil && len(existingActionPlans) > 0 { // all action timings from a specific tag shuld have the same list of user balances from the first one exitingAccountIds = existingActionPlans[0].AccountIds diff --git a/scheduler/scheduler.go b/scheduler/scheduler.go index c5120ccf9..ba5c5a6be 100644 --- a/scheduler/scheduler.go +++ b/scheduler/scheduler.go @@ -118,6 +118,7 @@ func (s *Scheduler) LoadActionPlans(storage engine.RatingStorage) { if toBeSaved { engine.Guardian.Guard(func() (interface{}, error) { storage.SetActionPlans(key, newApls) + storage.CacheRatingPrefixValues(map[string][]string{utils.ACTION_PLAN_PREFIX: []string{key}}) return 0, nil }, 0, utils.ACTION_PLAN_PREFIX) }