From f7edd20174c9bb92ee1944f629a8fe2e93d172b3 Mon Sep 17 00:00:00 2001 From: DanB Date: Wed, 31 Aug 2016 11:43:33 +0200 Subject: [PATCH] Cache redesign, fixing transactions mechanism --- apier/v1/accounts.go | 18 +-- apier/v1/apier.go | 32 ++-- apier/v1/derivedcharging.go | 4 +- apier/v1/scheduler.go | 2 +- apier/v1/triggers.go | 16 +- apier/v2/accounts.go | 4 +- apier/v2/apier.go | 6 +- cache2go/cache.go | 178 ++++++++++++---------- cache2go/cache_store.go | 103 +++++++------ cache2go/cache_test.go | 115 +++++++++++---- cmd/cgr-engine/cgr-engine.go | 2 +- cmd/cgr-engine/rater.go | 2 +- engine/account.go | 18 +-- engine/account_test.go | 4 +- engine/action.go | 8 +- engine/action_plan.go | 2 +- engine/action_trigger.go | 2 +- engine/actions_test.go | 26 ++-- engine/aliases.go | 22 +-- engine/aliases_test.go | 12 +- engine/balances.go | 2 +- engine/callcost.go | 2 +- engine/calldesc.go | 2 +- engine/calldesc_test.go | 58 ++++---- engine/cdrstats.go | 2 +- engine/destinations.go | 2 +- engine/destinations_test.go | 16 +- engine/handler_derivedcharging.go | 4 +- engine/lcr.go | 2 +- engine/ratingplan_test.go | 4 +- engine/ratingprofile.go | 10 +- engine/reqfilter.go | 2 +- engine/reqfilter_test.go | 2 +- engine/reslimiter.go | 2 +- engine/reslimiter_test.go | 6 +- engine/responder_test.go | 20 +-- engine/sharedgroup_test.go | 6 +- engine/storage_interface.go | 80 +++++----- engine/storage_map.go | 228 +++++++++++++++-------------- engine/storage_mongo_datadb.go | 198 +++++++++++++------------ engine/storage_redis.go | 212 ++++++++++++++------------- engine/storage_redis_local_test.go | 6 +- engine/storage_test.go | 38 ++--- engine/tp_reader.go | 54 +++---- engine/version.go | 2 +- utils/consts.go | 1 + 46 files changed, 823 insertions(+), 714 deletions(-) diff --git a/apier/v1/accounts.go b/apier/v1/accounts.go index 5715b69fd..e8ae38ed2 100644 --- a/apier/v1/accounts.go +++ b/apier/v1/accounts.go @@ -90,7 +90,7 @@ func (self *ApierV1) RemActionTiming(attrs AttrRemActionTiming, reply *string) e } } _, err := engine.Guardian.Guard(func() (interface{}, error) { - ap, err := self.RatingDb.GetActionPlan(attrs.ActionPlanId, false) + ap, err := self.RatingDb.GetActionPlan(attrs.ActionPlanId, false, utils.NonTransactional) if err != nil { return 0, err } else if ap == nil { @@ -100,7 +100,7 @@ func (self *ApierV1) RemActionTiming(attrs AttrRemActionTiming, reply *string) e if attrs.Tenant != "" && attrs.Account != "" { accID := utils.AccountKey(attrs.Tenant, attrs.Account) delete(ap.AccountIDs, accID) - err = self.RatingDb.SetActionPlan(ap.Id, ap, true) + err = self.RatingDb.SetActionPlan(ap.Id, ap, true, utils.NonTransactional) goto UPDATE } @@ -112,13 +112,13 @@ func (self *ApierV1) RemActionTiming(attrs AttrRemActionTiming, reply *string) e break } } - err = self.RatingDb.SetActionPlan(ap.Id, ap, true) + err = self.RatingDb.SetActionPlan(ap.Id, ap, true, utils.NonTransactional) goto UPDATE } if attrs.ActionPlanId != "" { // delete the entire action plan ap.ActionTimings = nil // will delete the action plan - err = self.RatingDb.SetActionPlan(ap.Id, ap, true) + err = self.RatingDb.SetActionPlan(ap.Id, ap, true, utils.NonTransactional) goto UPDATE } UPDATE: @@ -158,7 +158,7 @@ func (self *ApierV1) SetAccount(attr utils.AttrSetAccount, reply *string) error _, err := engine.Guardian.Guard(func() (interface{}, error) { var ap *engine.ActionPlan - ap, err := self.RatingDb.GetActionPlan(attr.ActionPlanId, false) + ap, err := self.RatingDb.GetActionPlan(attr.ActionPlanId, false, utils.NonTransactional) if err != nil { return 0, err } @@ -181,7 +181,7 @@ func (self *ApierV1) SetAccount(attr utils.AttrSetAccount, reply *string) error } } } - if err := self.RatingDb.SetActionPlan(attr.ActionPlanId, ap, true); err != nil { + if err := self.RatingDb.SetActionPlan(attr.ActionPlanId, ap, true, utils.NonTransactional); err != nil { return 0, err } } @@ -201,7 +201,7 @@ func (self *ApierV1) SetAccount(attr utils.AttrSetAccount, reply *string) error if _, exists := ap.AccountIDs[accID]; exists { delete(ap.AccountIDs, accID) // clean from cache - cache2go.RemKey(utils.ACTION_PLAN_PREFIX + actionPlanID) + cache2go.RemKey(utils.ACTION_PLAN_PREFIX+actionPlanID, true, utils.NonTransactional) } } @@ -213,7 +213,7 @@ func (self *ApierV1) SetAccount(attr utils.AttrSetAccount, reply *string) error } if len(attr.ActionTriggersId) != 0 { - atrs, err := self.RatingDb.GetActionTriggers(attr.ActionTriggersId, false) + atrs, err := self.RatingDb.GetActionTriggers(attr.ActionTriggersId, false, utils.NonTransactional) if err != nil { return 0, err } @@ -271,7 +271,7 @@ func (self *ApierV1) RemoveAccount(attr utils.AttrRemoveAccount, reply *string) } for actionPlanID, ap := range dirtyActionPlans { - if err := self.RatingDb.SetActionPlan(actionPlanID, ap, true); err != nil { + if err := self.RatingDb.SetActionPlan(actionPlanID, ap, true, utils.NonTransactional); err != nil { return 0, err } } diff --git a/apier/v1/apier.go b/apier/v1/apier.go index a04a1c7c0..3e335ac6d 100644 --- a/apier/v1/apier.go +++ b/apier/v1/apier.go @@ -53,7 +53,7 @@ type ApierV1 struct { } func (self *ApierV1) GetDestination(dstId string, reply *engine.Destination) error { - if dst, err := self.RatingDb.GetDestination(dstId, false); err != nil { + if dst, err := self.RatingDb.GetDestination(dstId, false, utils.NonTransactional); err != nil { return utils.ErrNotFound } else { *reply = *dst @@ -70,7 +70,7 @@ func (self *ApierV1) RemoveDestination(attr AttrRemoveDestination, reply *string var err error for _, dstID := range attr.DestinationIDs { if len(attr.Prefixes) == 0 { - if err = self.RatingDb.RemoveDestination(dstID); err != nil { + if err = self.RatingDb.RemoveDestination(dstID, utils.NonTransactional); err != nil { *reply = err.Error() break } else { @@ -88,7 +88,7 @@ func (self *ApierV1) RemoveDestination(attr AttrRemoveDestination, reply *string } func (apier *ApierV1) GetSharedGroup(sgId string, reply *engine.SharedGroup) error { - if sg, err := apier.RatingDb.GetSharedGroup(sgId, false); err != nil && err != utils.ErrNotFound { // Not found is not an error here + if sg, err := apier.RatingDb.GetSharedGroup(sgId, false, utils.NonTransactional); err != nil && err != utils.ErrNotFound { // Not found is not an error here return err } else { if sg != nil { @@ -111,7 +111,7 @@ func (self *ApierV1) SetDestination(attrs utils.AttrSetDestination, reply *strin } } dest := &engine.Destination{Id: attrs.Id, Prefixes: attrs.Prefixes} - if err := self.RatingDb.SetDestination(dest); err != nil { + if err := self.RatingDb.SetDestination(dest, utils.NonTransactional); err != nil { return utils.NewErrServerError(err) } *reply = OK @@ -119,7 +119,7 @@ func (self *ApierV1) SetDestination(attrs utils.AttrSetDestination, reply *strin } func (self *ApierV1) GetRatingPlan(rplnId string, reply *engine.RatingPlan) error { - if rpln, err := self.RatingDb.GetRatingPlan(rplnId, false); err != nil { + if rpln, err := self.RatingDb.GetRatingPlan(rplnId, false, utils.NonTransactional); err != nil { return utils.ErrNotFound } else { *reply = *rpln @@ -412,7 +412,7 @@ func (self *ApierV1) SetRatingProfile(attrs AttrSetRatingProfile, reply *string) return utils.NewErrServerError(err) } else if exists { var err error - if rpfl, err = self.RatingDb.GetRatingProfile(keyId, false); err != nil { + if rpfl, err = self.RatingDb.GetRatingProfile(keyId, false, utils.NonTransactional); err != nil { return utils.NewErrServerError(err) } } @@ -433,10 +433,10 @@ func (self *ApierV1) SetRatingProfile(attrs AttrSetRatingProfile, reply *string) rpfl.RatingPlanActivations = append(rpfl.RatingPlanActivations, &engine.RatingPlanActivation{ActivationTime: at, RatingPlanId: ra.RatingPlanId, FallbackKeys: utils.FallbackSubjKeys(tpRpf.Direction, tpRpf.Tenant, tpRpf.Category, ra.FallbackSubjects)}) } - if err := self.RatingDb.SetRatingProfile(rpfl); err != nil { + if err := self.RatingDb.SetRatingProfile(rpfl, utils.NonTransactional); err != nil { return utils.NewErrServerError(err) } - cache2go.RemPrefixKey(utils.RATING_PLAN_PREFIX) + cache2go.RemPrefixKey(utils.RATING_PLAN_PREFIX, true, "") self.RatingDb.PreloadCacheForPrefix(utils.RATING_PLAN_PREFIX) *reply = OK return nil @@ -503,7 +503,7 @@ func (self *ApierV1) SetActions(attrs utils.AttrSetActions, reply *string) error } storeActions[idx] = a } - if err := self.RatingDb.SetActions(attrs.ActionsId, storeActions); err != nil { + if err := self.RatingDb.SetActions(attrs.ActionsId, storeActions, utils.NonTransactional); err != nil { return utils.NewErrServerError(err) } *reply = OK @@ -516,7 +516,7 @@ func (self *ApierV1) GetActions(actsId string, reply *[]*utils.TPAction) error { return fmt.Errorf("%s ActionsId: %s", utils.ErrMandatoryIeMissing.Error(), actsId) } acts := make([]*utils.TPAction, 0) - engActs, err := self.RatingDb.GetActions(actsId, false) + engActs, err := self.RatingDb.GetActions(actsId, false, utils.NonTransactional) if err != nil { return utils.NewErrServerError(err) } @@ -605,7 +605,7 @@ func (self *ApierV1) SetActionPlan(attrs AttrSetActionPlan, reply *string) error ActionsID: apiAtm.ActionsId, }) } - if err := self.RatingDb.SetActionPlan(ap.Id, ap, true); err != nil { + if err := self.RatingDb.SetActionPlan(ap.Id, ap, true, utils.NonTransactional); err != nil { return utils.NewErrServerError(err) } if attrs.ReloadScheduler { @@ -633,7 +633,7 @@ func (self *ApierV1) GetActionPlan(attr AttrGetActionPlan, reply *[]*engine.Acti result = append(result, apls) } } else { - apls, err := self.RatingDb.GetActionPlan(attr.Id, false) + apls, err := self.RatingDb.GetActionPlan(attr.Id, false, utils.NonTransactional) if err != nil { return err } @@ -769,7 +769,7 @@ func (self *ApierV1) GetCacheStats(attrs utils.AttrCacheStats, reply *utils.Cach } cs.Users = len(ups) } - if loadHistInsts, err := self.AccountDb.GetLoadHistory(1, false); err != nil || len(loadHistInsts) == 0 { + if loadHistInsts, err := self.AccountDb.GetLoadHistory(1, false, utils.NonTransactional); err != nil || len(loadHistInsts) == 0 { if err != nil { // Not really an error here since we only count in cache utils.Logger.Warning(fmt.Sprintf("ApierV1.GetCacheStats, error on GetLoadHistory: %s", err.Error())) } @@ -957,7 +957,7 @@ func (self *ApierV1) RemoveRatingProfile(attr AttrRemoveRatingProfile, reply *st return utils.ErrMandatoryIeMissing } _, err := engine.Guardian.Guard(func() (interface{}, error) { - err := self.RatingDb.RemoveRatingProfile(attr.GetId()) + err := self.RatingDb.RemoveRatingProfile(attr.GetId(), utils.NonTransactional) if err != nil { return 0, err } @@ -979,7 +979,7 @@ func (self *ApierV1) GetLoadHistory(attrs utils.Paginator, reply *[]*utils.LoadI } else if attrs.Limit != nil { nrItems = *attrs.Limit } - loadHist, err := self.AccountDb.GetLoadHistory(nrItems, true) + loadHist, err := self.AccountDb.GetLoadHistory(nrItems, true, utils.NonTransactional) if err != nil { return utils.NewErrServerError(err) } @@ -1049,7 +1049,7 @@ func (self *ApierV1) RemoveActions(attr AttrRemoveActions, reply *string) error } */ for _, aID := range attr.ActionIDs { - if err := self.RatingDb.RemoveActions(aID); err != nil { + if err := self.RatingDb.RemoveActions(aID, utils.NonTransactional); err != nil { *reply = err.Error() return err } diff --git a/apier/v1/derivedcharging.go b/apier/v1/derivedcharging.go index abc953943..617bfbfae 100644 --- a/apier/v1/derivedcharging.go +++ b/apier/v1/derivedcharging.go @@ -79,7 +79,7 @@ func (self *ApierV1) SetDerivedChargers(attrs AttrSetDerivedChargers, reply *str } dstIds := strings.Split(attrs.DestinationIds, utils.INFIELD_SEP) dcs := &utils.DerivedChargers{DestinationIDs: utils.NewStringMap(dstIds...), Chargers: attrs.DerivedChargers} - if err := self.RatingDb.SetDerivedChargers(dcKey, dcs); err != nil { + if err := self.RatingDb.SetDerivedChargers(dcKey, dcs, utils.NonTransactional); err != nil { return utils.NewErrServerError(err) } *reply = utils.OK @@ -106,7 +106,7 @@ func (self *ApierV1) RemDerivedChargers(attrs AttrRemDerivedChargers, reply *str if len(attrs.Subject) == 0 { attrs.Subject = utils.ANY } - if err := self.RatingDb.SetDerivedChargers(utils.DerivedChargersKey(attrs.Direction, attrs.Tenant, attrs.Category, attrs.Account, attrs.Subject), nil); err != nil { + if err := self.RatingDb.SetDerivedChargers(utils.DerivedChargersKey(attrs.Direction, attrs.Tenant, attrs.Category, attrs.Account, attrs.Subject), nil, utils.NonTransactional); err != nil { return utils.NewErrServerError(err) } else { *reply = "OK" diff --git a/apier/v1/scheduler.go b/apier/v1/scheduler.go index f8ebda45c..05ca96fa0 100644 --- a/apier/v1/scheduler.go +++ b/apier/v1/scheduler.go @@ -179,7 +179,7 @@ type AttrsExecuteScheduledActions struct { func (self *ApierV1) ExecuteScheduledActions(attr AttrsExecuteScheduledActions, reply *string) error { if attr.ActionPlanID != "" { // execute by ActionPlanID - apl, err := self.RatingDb.GetActionPlan(attr.ActionPlanID, false) + apl, err := self.RatingDb.GetActionPlan(attr.ActionPlanID, false, utils.NonTransactional) if err != nil { *reply = err.Error() return err diff --git a/apier/v1/triggers.go b/apier/v1/triggers.go index 3292aeeb5..99711185d 100644 --- a/apier/v1/triggers.go +++ b/apier/v1/triggers.go @@ -53,7 +53,7 @@ func (self *ApierV1) AddAccountActionTriggers(attr AttrAddAccountActionTriggers, account.ActionTriggers = make(engine.ActionTriggers, 0) } for _, actionTriggerID := range *attr.ActionTriggerIDs { - atrs, err := self.RatingDb.GetActionTriggers(actionTriggerID, false) + atrs, err := self.RatingDb.GetActionTriggers(actionTriggerID, false, utils.NonTransactional) if err != nil { return 0, err @@ -328,7 +328,7 @@ func (self *ApierV1) RemoveActionTrigger(attr AttrRemoveActionTrigger, reply *st return utils.NewErrMandatoryIeMissing(missing...) } if attr.UniqueID == "" { - err := self.RatingDb.RemoveActionTriggers(attr.GroupID) + err := self.RatingDb.RemoveActionTriggers(attr.GroupID, utils.NonTransactional) if err != nil { *reply = err.Error() } else { @@ -336,7 +336,7 @@ func (self *ApierV1) RemoveActionTrigger(attr AttrRemoveActionTrigger, reply *st } return err } else { - atrs, err := self.RatingDb.GetActionTriggers(attr.GroupID, false) + atrs, err := self.RatingDb.GetActionTriggers(attr.GroupID, false, utils.NonTransactional) if err != nil { *reply = err.Error() return err @@ -349,7 +349,7 @@ func (self *ApierV1) RemoveActionTrigger(attr AttrRemoveActionTrigger, reply *st remainingAtrs = append(remainingAtrs, atr) } // set the cleared list back - err = self.RatingDb.SetActionTriggers(attr.GroupID, remainingAtrs) + err = self.RatingDb.SetActionTriggers(attr.GroupID, remainingAtrs, utils.NonTransactional) if err != nil { *reply = err.Error() } else { @@ -390,7 +390,7 @@ func (self *ApierV1) SetActionTrigger(attr AttrSetActionTrigger, reply *string) return utils.NewErrMandatoryIeMissing(missing...) } - atrs, _ := self.RatingDb.GetActionTriggers(attr.GroupID, false) + atrs, _ := self.RatingDb.GetActionTriggers(attr.GroupID, false, utils.NonTransactional) var newAtr *engine.ActionTrigger if attr.UniqueID != "" { //search for exiting one @@ -495,7 +495,7 @@ func (self *ApierV1) SetActionTrigger(attr AttrSetActionTrigger, reply *string) newAtr.ActionsID = *attr.ActionsID } - if err := self.RatingDb.SetActionTriggers(attr.GroupID, atrs); err != nil { + if err := self.RatingDb.SetActionTriggers(attr.GroupID, atrs, utils.NonTransactional); err != nil { *reply = err.Error() return err } @@ -512,7 +512,7 @@ func (self *ApierV1) GetActionTriggers(attr AttrGetActionTriggers, atrs *engine. var allAttrs engine.ActionTriggers if len(attr.GroupIDs) > 0 { for _, key := range attr.GroupIDs { - getAttrs, err := self.RatingDb.GetActionTriggers(key, false) + getAttrs, err := self.RatingDb.GetActionTriggers(key, false, utils.NonTransactional) if err != nil { return err } @@ -525,7 +525,7 @@ func (self *ApierV1) GetActionTriggers(attr AttrGetActionTriggers, atrs *engine. return err } for _, key := range keys { - getAttrs, err := self.RatingDb.GetActionTriggers(key[len(utils.ACTION_TRIGGER_PREFIX):], false) + getAttrs, err := self.RatingDb.GetActionTriggers(key[len(utils.ACTION_TRIGGER_PREFIX):], false, utils.NonTransactional) if err != nil { return err } diff --git a/apier/v2/accounts.go b/apier/v2/accounts.go index 1b385244e..c0f89141a 100644 --- a/apier/v2/accounts.go +++ b/apier/v2/accounts.go @@ -157,7 +157,7 @@ func (self *ApierV2) SetAccount(attr AttrSetAccount, reply *string) error { } } for actionPlanID, ap := range dirtyActionPlans { - if err := self.RatingDb.SetActionPlan(actionPlanID, ap, true); err != nil { + if err := self.RatingDb.SetActionPlan(actionPlanID, ap, true, utils.NonTransactional); err != nil { return 0, err } } @@ -173,7 +173,7 @@ func (self *ApierV2) SetAccount(attr AttrSetAccount, reply *string) error { ub.ActionTriggers = make(engine.ActionTriggers, 0) } for _, actionTriggerID := range *attr.ActionTriggerIDs { - atrs, err := self.RatingDb.GetActionTriggers(actionTriggerID, false) + atrs, err := self.RatingDb.GetActionTriggers(actionTriggerID, false, utils.NonTransactional) if err != nil { return 0, err } diff --git a/apier/v2/apier.go b/apier/v2/apier.go index 45f17836b..fbf29bedc 100644 --- a/apier/v2/apier.go +++ b/apier/v2/apier.go @@ -227,7 +227,7 @@ func (self *ApierV2) LoadTariffPlanFromFolder(attrs utils.AttrLoadTpFromFolder, return err } } - loadHistList, err := self.AccountDb.GetLoadHistory(1, true) + loadHistList, err := self.AccountDb.GetLoadHistory(1, true, utils.NonTransactional) if err != nil { return err } @@ -278,7 +278,7 @@ func (self *ApierV2) GetActions(attr AttrGetActions, reply *map[string]engine.Ac retActions := make(map[string]engine.Actions) for _, accKey := range limitedActions { key := accKey[len(utils.ACTION_PREFIX):] - acts, err := self.RatingDb.GetActions(key, false) + acts, err := self.RatingDb.GetActions(key, false, utils.NonTransactional) if err != nil { return utils.NewErrServerError(err) } @@ -312,7 +312,7 @@ func (self *ApierV2) GetDestinations(attr AttrGetDestinations, reply *[]*engine. } } for _, destID := range attr.DestinationIDs { - dst, err := self.RatingDb.GetDestination(destID, false) + dst, err := self.RatingDb.GetDestination(destID, false, utils.NonTransactional) if err != nil { return err } diff --git a/cache2go/cache.go b/cache2go/cache.go index 6c015207e..408d24e85 100644 --- a/cache2go/cache.go +++ b/cache2go/cache.go @@ -1,35 +1,50 @@ -//Simple caching library with expiration capabilities +/* +Real-time Charging System for Telecom & ISP environments +Copyright (C) ITsysCOM GmbH + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ package cache2go import ( "sync" "github.com/cgrates/cgrates/config" + "github.com/cgrates/cgrates/utils" ) const ( - PREFIX_LEN = 4 - KIND_ADD = "ADD" - KIND_REM = "REM" - KIND_PRF = "PRF" - DOUBLE_CACHE = true + PREFIX_LEN = 4 + ADD = "ADD" + REM = "REM" + REM_PREFIX = "PRF" ) var ( - mux sync.RWMutex - cache cacheStore - cfg *config.CacheConfig + cache cacheStore + cacheMux sync.RWMutex + cfg *config.CacheConfig // transaction stuff - transactionBuffer []*transactionItem - transactionMux sync.Mutex - transactionON = false - transactionLock = false + transactionBuffer map[string][]*transactionItem // Queue tasks based on transactionID + transBufMux sync.Mutex // Protects the transactionBuffer + transactionMux sync.Mutex // Queue transactions on commit ) type transactionItem struct { - key string - value interface{} - kind string + verb string // action which will be executed on cache + key string // item key + value interface{} // item value } func init() { @@ -39,101 +54,110 @@ func init() { func NewCache(cacheCfg *config.CacheConfig) { cfg = cacheCfg cache = newLruStore() + transactionBuffer = make(map[string][]*transactionItem) // map[transactionID][]*transactionItem } -func BeginTransaction() { +func BeginTransaction() string { + transID := utils.GenUUID() + transBufMux.Lock() + transactionBuffer[transID] = make([]*transactionItem, 0) + transBufMux.Unlock() + return transID +} + +func RollbackTransaction(transID string) { + transBufMux.Lock() + delete(transactionBuffer, transID) + transBufMux.Unlock() +} + +func CommitTransaction(transID string) { transactionMux.Lock() - transactionLock = true - transactionON = true -} - -func RollbackTransaction() { - transactionBuffer = nil - transactionLock = false - transactionON = false - transactionMux.Unlock() -} - -func CommitTransaction() { - transactionON = false - // apply all transactioned items - mux.Lock() - for _, item := range transactionBuffer { - switch item.kind { - case KIND_REM: - RemKey(item.key) - case KIND_PRF: - RemPrefixKey(item.key) - case KIND_ADD: - Set(item.key, item.value) + transBufMux.Lock() + // apply all transactioned items in one shot + cacheMux.Lock() + for _, item := range transactionBuffer[transID] { + switch item.verb { + case REM: + RemKey(item.key, true, transID) + case REM_PREFIX: + RemPrefixKey(item.key, true, transID) + case ADD: + Set(item.key, item.value, true, transID) } } - mux.Unlock() - transactionBuffer = nil - transactionLock = false + cacheMux.Unlock() + delete(transactionBuffer, transID) + transBufMux.Unlock() transactionMux.Unlock() } // The function to be used to cache a key/value pair when expiration is not needed -func Set(key string, value interface{}) { - if !transactionLock { - mux.Lock() - defer mux.Unlock() - } - if !transactionON { +func Set(key string, value interface{}, commit bool, transID string) { + if commit { + if transID == "" { // Lock locally + cacheMux.Lock() + defer cacheMux.Unlock() + } cache.Put(key, value) //log.Println("ADD: ", key) } else { - transactionBuffer = append(transactionBuffer, &transactionItem{key: key, value: value, kind: KIND_ADD}) + transBufMux.Lock() + transactionBuffer[transID] = append(transactionBuffer[transID], &transactionItem{verb: ADD, key: key, value: value}) + transBufMux.Unlock() } } -// The function to extract a value for a key that never expire -func Get(key string) (interface{}, bool) { - mux.RLock() - defer mux.RUnlock() - return cache.Get(key) -} - -func RemKey(key string) { - if !transactionLock { - mux.Lock() - defer mux.Unlock() - } - if !transactionON { +func RemKey(key string, commit bool, transID string) { + if commit { + if transID == "" { // Lock per operation not transaction + cacheMux.Lock() + defer cacheMux.Unlock() + } cache.Delete(key) } else { - transactionBuffer = append(transactionBuffer, &transactionItem{key: key, kind: KIND_REM}) + transBufMux.Lock() + transactionBuffer[transID] = append(transactionBuffer[transID], &transactionItem{verb: REM, key: key}) + transBufMux.Unlock() } } -func RemPrefixKey(prefix string) { - if !transactionLock { - mux.Lock() - defer mux.Unlock() - } - if !transactionON { +func RemPrefixKey(prefix string, commit bool, transID string) { + if commit { + if transID == "" { // Lock locally + cacheMux.Lock() + defer cacheMux.Unlock() + } cache.DeletePrefix(prefix) } else { - transactionBuffer = append(transactionBuffer, &transactionItem{key: prefix, kind: KIND_PRF}) + transBufMux.Lock() + transactionBuffer[transID] = append(transactionBuffer[transID], &transactionItem{verb: REM_PREFIX, key: prefix}) + transBufMux.Unlock() } } // Delete all keys from cache func Flush() { - mux.Lock() - defer mux.Unlock() + cacheMux.Lock() cache = newLruStore() + cacheMux.Unlock() +} + +// The function to extract a value for a key that never expire +func Get(key string) (interface{}, bool) { + cacheMux.RLock() + defer cacheMux.RUnlock() + return cache.Get(key) } func CountEntries(prefix string) (result int) { - mux.RLock() - defer mux.RUnlock() + cacheMux.RLock() + defer cacheMux.RUnlock() return cache.CountEntriesForPrefix(prefix) } func GetEntriesKeys(prefix string) (keys []string) { - mux.RLock() - defer mux.RUnlock() + cacheMux.RLock() + defer cacheMux.RUnlock() return cache.GetKeysForPrefix(prefix) } diff --git a/cache2go/cache_store.go b/cache2go/cache_store.go index 62c927c5e..0334aef9d 100644 --- a/cache2go/cache_store.go +++ b/cache2go/cache_store.go @@ -1,4 +1,20 @@ -//Simple caching library with expiration capabilities +/* +Real-time Charging System for Telecom & ISP environments +Copyright (C) ITsysCOM GmbH + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ package cache2go import ( @@ -93,84 +109,77 @@ func (cs cacheDoubleStore) GetKeysForPrefix(prefix string) (keys []string) { } // easy to be counted exported by prefix -type lrustore struct { - store map[string]*lru.Cache - sync.Mutex -} +type lrustore map[string]*lru.Cache -func newLruStore() *lrustore { - c := &lrustore{store: make(map[string]*lru.Cache)} - c.Lock() - defer c.Unlock() +func newLruStore() lrustore { + c := make(map[string]*lru.Cache) if cfg != nil && cfg.Destinations != nil { - c.store[utils.DESTINATION_PREFIX], _ = lru.New(cfg.Destinations.Limit) + c[utils.DESTINATION_PREFIX], _ = lru.New(cfg.Destinations.Limit) } else { - c.store[utils.DESTINATION_PREFIX], _ = lru.New(10000) + c[utils.DESTINATION_PREFIX], _ = lru.New(10000) } if cfg != nil && cfg.ReverseDestinations != nil { - c.store[utils.REVERSE_DESTINATION_PREFIX], _ = lru.New(cfg.ReverseDestinations.Limit) + c[utils.REVERSE_DESTINATION_PREFIX], _ = lru.New(cfg.ReverseDestinations.Limit) } else { - c.store[utils.REVERSE_DESTINATION_PREFIX], _ = lru.New(10000) + c[utils.REVERSE_DESTINATION_PREFIX], _ = lru.New(10000) } if cfg != nil && cfg.RatingPlans != nil { - c.store[utils.RATING_PLAN_PREFIX], _ = lru.New(cfg.RatingPlans.Limit) + c[utils.RATING_PLAN_PREFIX], _ = lru.New(cfg.RatingPlans.Limit) } else { - c.store[utils.RATING_PLAN_PREFIX], _ = lru.New(10000) + c[utils.RATING_PLAN_PREFIX], _ = lru.New(10000) } if cfg != nil && cfg.RatingProfiles != nil { - c.store[utils.RATING_PROFILE_PREFIX], _ = lru.New(cfg.RatingProfiles.Limit) + c[utils.RATING_PROFILE_PREFIX], _ = lru.New(cfg.RatingProfiles.Limit) } else { - c.store[utils.RATING_PROFILE_PREFIX], _ = lru.New(10000) + c[utils.RATING_PROFILE_PREFIX], _ = lru.New(10000) } if cfg != nil && cfg.Lcr != nil { - c.store[utils.LCR_PREFIX], _ = lru.New(cfg.Lcr.Limit) + c[utils.LCR_PREFIX], _ = lru.New(cfg.Lcr.Limit) } else { - c.store[utils.LCR_PREFIX], _ = lru.New(10000) + c[utils.LCR_PREFIX], _ = lru.New(10000) } if cfg != nil && cfg.CdrStats != nil { - c.store[utils.CDR_STATS_PREFIX], _ = lru.New(cfg.CdrStats.Limit) + c[utils.CDR_STATS_PREFIX], _ = lru.New(cfg.CdrStats.Limit) } else { - c.store[utils.CDR_STATS_PREFIX], _ = lru.New(10000) + c[utils.CDR_STATS_PREFIX], _ = lru.New(10000) } if cfg != nil && cfg.Actions != nil { - c.store[utils.ACTION_PREFIX], _ = lru.New(cfg.Actions.Limit) + c[utils.ACTION_PREFIX], _ = lru.New(cfg.Actions.Limit) } else { - c.store[utils.ACTION_PREFIX], _ = lru.New(10000) + c[utils.ACTION_PREFIX], _ = lru.New(10000) } if cfg != nil && cfg.ActionPlans != nil { - c.store[utils.ACTION_PLAN_PREFIX], _ = lru.New(cfg.ActionPlans.Limit) + c[utils.ACTION_PLAN_PREFIX], _ = lru.New(cfg.ActionPlans.Limit) } else { - c.store[utils.ACTION_PLAN_PREFIX], _ = lru.New(10000) + c[utils.ACTION_PLAN_PREFIX], _ = lru.New(10000) } if cfg != nil && cfg.ActionTriggers != nil { - c.store[utils.ACTION_TRIGGER_PREFIX], _ = lru.New(cfg.ActionTriggers.Limit) + c[utils.ACTION_TRIGGER_PREFIX], _ = lru.New(cfg.ActionTriggers.Limit) } else { - c.store[utils.ACTION_TRIGGER_PREFIX], _ = lru.New(10000) + c[utils.ACTION_TRIGGER_PREFIX], _ = lru.New(10000) } if cfg != nil && cfg.SharedGroups != nil { - c.store[utils.SHARED_GROUP_PREFIX], _ = lru.New(cfg.SharedGroups.Limit) + c[utils.SHARED_GROUP_PREFIX], _ = lru.New(cfg.SharedGroups.Limit) } else { - c.store[utils.SHARED_GROUP_PREFIX], _ = lru.New(10000) + c[utils.SHARED_GROUP_PREFIX], _ = lru.New(10000) } if cfg != nil && cfg.Aliases != nil { - c.store[utils.ALIASES_PREFIX], _ = lru.New(cfg.Aliases.Limit) + c[utils.ALIASES_PREFIX], _ = lru.New(cfg.Aliases.Limit) } else { - c.store[utils.ALIASES_PREFIX], _ = lru.New(10000) + c[utils.ALIASES_PREFIX], _ = lru.New(10000) } if cfg != nil && cfg.ReverseAliases != nil { - c.store[utils.REVERSE_ALIASES_PREFIX], _ = lru.New(cfg.ReverseAliases.Limit) + c[utils.REVERSE_ALIASES_PREFIX], _ = lru.New(cfg.ReverseAliases.Limit) } else { - c.store[utils.REVERSE_ALIASES_PREFIX], _ = lru.New(10000) + c[utils.REVERSE_ALIASES_PREFIX], _ = lru.New(10000) } return c } func (cs lrustore) Put(key string, value interface{}) { - cs.Lock() - defer cs.Unlock() prefix, key := key[:PREFIX_LEN], key[PREFIX_LEN:] - mp, ok := cs.store[prefix] + mp, ok := cs[prefix] if !ok { var err error mp, err = lru.New(10000) @@ -178,16 +187,14 @@ func (cs lrustore) Put(key string, value interface{}) { utils.Logger.Debug(fmt.Sprintf(": error at init: %v", err)) return } - cs.store[prefix] = mp + cs[prefix] = mp } mp.Add(key, value) } func (cs lrustore) Get(key string) (interface{}, bool) { - cs.Lock() - defer cs.Unlock() prefix, key := key[:PREFIX_LEN], key[PREFIX_LEN:] - if keyMap, ok := cs.store[prefix]; ok { + if keyMap, ok := cs[prefix]; ok { if ti, exists := keyMap.Get(key); exists { return ti, true } @@ -196,34 +203,26 @@ func (cs lrustore) Get(key string) (interface{}, bool) { } func (cs lrustore) Delete(key string) { - cs.Lock() - defer cs.Unlock() prefix, key := key[:PREFIX_LEN], key[PREFIX_LEN:] - if keyMap, ok := cs.store[prefix]; ok { + if keyMap, ok := cs[prefix]; ok { keyMap.Remove(key) } } func (cs lrustore) DeletePrefix(prefix string) { - cs.Lock() - defer cs.Unlock() - delete(cs.store, prefix) + delete(cs, prefix) } func (cs lrustore) CountEntriesForPrefix(prefix string) int { - cs.Lock() - defer cs.Unlock() - if m, ok := cs.store[prefix]; ok { + if m, ok := cs[prefix]; ok { return m.Len() } return 0 } func (cs lrustore) GetKeysForPrefix(prefix string) (keys []string) { - cs.Lock() - defer cs.Unlock() prefix, key := prefix[:PREFIX_LEN], prefix[PREFIX_LEN:] - if keyMap, ok := cs.store[prefix]; ok { + if keyMap, ok := cs[prefix]; ok { for _, iterKey := range keyMap.Keys() { iterKeyString := iterKey.(string) if len(key) == 0 || strings.HasPrefix(iterKeyString, key) { diff --git a/cache2go/cache_test.go b/cache2go/cache_test.go index b95386d8b..540cb6eac 100644 --- a/cache2go/cache_test.go +++ b/cache2go/cache_test.go @@ -1,73 +1,110 @@ +/* +Real-time Charging System for Telecom & ISP environments +Copyright (C) ITsysCOM GmbH + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + package cache2go import ( + "sync" "testing" ) func TestRemKey(t *testing.T) { - Set("t11_mm", "test") + Set("t11_mm", "test", true, "") if t1, ok := Get("t11_mm"); !ok || t1 != "test" { t.Error("Error setting cache: ", ok, t1) } - RemKey("t11_mm") + RemKey("t11_mm", true, "") if t1, ok := Get("t11_mm"); ok || t1 == "test" { t.Error("Error removing cached key") } } func TestTransaction(t *testing.T) { - BeginTransaction() - Set("t11_mm", "test") + transID := BeginTransaction() + Set("t11_mm", "test", false, transID) if t1, ok := Get("t11_mm"); ok || t1 == "test" { t.Error("Error in transaction cache") } - Set("t12_mm", "test") - RemKey("t11_mm") - CommitTransaction() + Set("t12_mm", "test", false, transID) + RemKey("t11_mm", false, transID) + if _, hasTransID := transactionBuffer[transID]; !hasTransID { + t.Error("Does not have transactionID") + } + CommitTransaction(transID) if t1, ok := Get("t12_mm"); !ok || t1 != "test" { t.Error("Error commiting transaction") } if t1, ok := Get("t11_mm"); ok || t1 == "test" { t.Error("Error in transaction cache") } + if _, hasTransID := transactionBuffer[transID]; hasTransID { + t.Error("Should not longer have transactionID") + } } func TestTransactionRem(t *testing.T) { - BeginTransaction() - Set("t21_mm", "test") - Set("t21_nn", "test") - RemPrefixKey("t21_") - CommitTransaction() + transID := BeginTransaction() + Set("t21_mm", "test", false, transID) + Set("t21_nn", "test", false, transID) + RemPrefixKey("t21_", false, transID) + if _, hasTransID := transactionBuffer[transID]; !hasTransID { + t.Error("Does not have transactionID") + } + CommitTransaction(transID) if t1, ok := Get("t21_mm"); ok || t1 == "test" { t.Error("Error commiting transaction") } if t1, ok := Get("t21_nn"); ok || t1 == "test" { t.Error("Error in transaction cache") } + if _, hasTransID := transactionBuffer[transID]; hasTransID { + t.Error("Should not longer have transactionID") + } } func TestTransactionRollback(t *testing.T) { - BeginTransaction() - Set("t31_mm", "test") + transID := BeginTransaction() + Set("t31_mm", "test", false, transID) if t1, ok := Get("t31_mm"); ok || t1 == "test" { t.Error("Error in transaction cache") } - Set("t32_mm", "test") - RollbackTransaction() + Set("t32_mm", "test", false, transID) + if _, hasTransID := transactionBuffer[transID]; !hasTransID { + t.Error("Does not have transactionID") + } + RollbackTransaction(transID) if t1, ok := Get("t32_mm"); ok || t1 == "test" { t.Error("Error commiting transaction") } if t1, ok := Get("t31_mm"); ok || t1 == "test" { t.Error("Error in transaction cache") } + if _, hasTransID := transactionBuffer[transID]; hasTransID { + t.Error("Should not longer have transactionID") + } } func TestTransactionRemBefore(t *testing.T) { - BeginTransaction() - RemPrefixKey("t41_") - Set("t41_mm", "test") - Set("t41_nn", "test") - CommitTransaction() + transID := BeginTransaction() + RemPrefixKey("t41_", false, transID) + Set("t41_mm", "test", false, transID) + Set("t41_nn", "test", false, transID) + CommitTransaction(transID) if t1, ok := Get("t41_mm"); !ok || t1 != "test" { t.Error("Error commiting transaction") } @@ -77,9 +114,9 @@ func TestTransactionRemBefore(t *testing.T) { } func TestRemPrefixKey(t *testing.T) { - Set("xxx_t1", "test") - Set("yyy_t1", "test") - RemPrefixKey("xxx_") + Set("xxx_t1", "test", true, "") + Set("yyy_t1", "test", true, "") + RemPrefixKey("xxx_", true, "") _, okX := Get("xxx_t1") _, okY := Get("yyy_t1") if okX || !okY { @@ -87,13 +124,29 @@ func TestRemPrefixKey(t *testing.T) { } } -/*func TestCount(t *testing.T) { - Set("dst_A1", "1") - Set("dst_A2", "2") - Set("rpf_A3", "3") - Set("dst_A4", "4") - Set("dst_A5", "5") +func TestCacheCount(t *testing.T) { + Set("dst_A1", "1", true, "") + Set("dst_A2", "2", true, "") + Set("rpf_A3", "3", true, "") + Set("dst_A4", "4", true, "") + Set("dst_A5", "5", true, "") if CountEntries("dst_") != 4 { t.Error("Error countiong entries: ", CountEntries("dst_")) } -}*/ +} + +// Try concurrent read/write of the cache +func TestCacheConcurrent(t *testing.T) { + s := &struct{ Prefix string }{Prefix: "+49"} + Set("dst_DE", s, true, "") + wg := new(sync.WaitGroup) + for i := 0; i < 1000; i++ { + wg.Add(1) + go func() { + Get("dst_DE") + wg.Done() + }() + } + s.Prefix = "+491" + wg.Wait() +} diff --git a/cmd/cgr-engine/cgr-engine.go b/cmd/cgr-engine/cgr-engine.go index 2f0d93951..0407702d4 100644 --- a/cmd/cgr-engine/cgr-engine.go +++ b/cmd/cgr-engine/cgr-engine.go @@ -407,7 +407,7 @@ func startPubSubServer(internalPubSubSChan chan rpcclient.RpcClientConnection, a func startAliasesServer(internalAliaseSChan chan rpcclient.RpcClientConnection, accountDb engine.AccountingStorage, server *utils.Server, exitChan chan bool) { aliasesServer := engine.NewAliasHandler(accountDb) server.RpcRegisterName("AliasesV1", aliasesServer) - loadHist, err := accountDb.GetLoadHistory(1, true) + loadHist, err := accountDb.GetLoadHistory(1, true, utils.NonTransactional) if err != nil || len(loadHist) == 0 { utils.Logger.Info(fmt.Sprintf("could not get load history: %v (%v)", loadHist, err)) internalAliaseSChan <- aliasesServer diff --git a/cmd/cgr-engine/rater.go b/cmd/cgr-engine/rater.go index 64db49e81..e36ae9ad2 100644 --- a/cmd/cgr-engine/rater.go +++ b/cmd/cgr-engine/rater.go @@ -64,7 +64,7 @@ func startRater(internalRaterChan chan rpcclient.RpcClientConnection, cacheDoneC go func() { defer close(cacheTaskChan) - loadHist, err := accountDb.GetLoadHistory(1, true) + loadHist, err := accountDb.GetLoadHistory(1, true, utils.NonTransactional) if err != nil || len(loadHist) == 0 { utils.Logger.Info(fmt.Sprintf("could not get load history: %v (%v)", loadHist, err)) cacheDoneChan <- struct{}{} diff --git a/engine/account.go b/engine/account.go index b75806088..a9d809e01 100644 --- a/engine/account.go +++ b/engine/account.go @@ -55,7 +55,7 @@ func (ub *Account) getCreditForPrefix(cd *CallDescriptor) (duration time.Duratio for _, cb := range creditBalances { if len(cb.SharedGroups) > 0 { for sg := range cb.SharedGroups { - if sharedGroup, _ := ratingStorage.GetSharedGroup(sg, false); sharedGroup != nil { + if sharedGroup, _ := ratingStorage.GetSharedGroup(sg, false, utils.NonTransactional); sharedGroup != nil { sgb := sharedGroup.GetBalances(cd.Destination, cd.Category, cd.Direction, utils.MONETARY, ub) sgb = sharedGroup.SortBalancesByStrategy(cb, sgb) extendedCreditBalances = append(extendedCreditBalances, sgb...) @@ -69,7 +69,7 @@ func (ub *Account) getCreditForPrefix(cd *CallDescriptor) (duration time.Duratio for _, mb := range unitBalances { if len(mb.SharedGroups) > 0 { for sg := range mb.SharedGroups { - if sharedGroup, _ := ratingStorage.GetSharedGroup(sg, false); sharedGroup != nil { + if sharedGroup, _ := ratingStorage.GetSharedGroup(sg, false, utils.NonTransactional); sharedGroup != nil { sgb := sharedGroup.GetBalances(cd.Destination, cd.Category, cd.Direction, cd.TOR, ub) sgb = sharedGroup.SortBalancesByStrategy(mb, sgb) extendedMinuteBalances = append(extendedMinuteBalances, sgb...) @@ -137,7 +137,7 @@ func (acc *Account) setBalanceAction(a *Action) error { _, err := Guardian.Guard(func() (interface{}, error) { for sgID := range balance.SharedGroups { // add shared group member - sg, err := ratingStorage.GetSharedGroup(sgID, false) + sg, err := ratingStorage.GetSharedGroup(sgID, false, utils.NonTransactional) if err != nil || sg == nil { //than is problem utils.Logger.Warning(fmt.Sprintf("Could not get shared group: %v", sgID)) @@ -148,7 +148,7 @@ func (acc *Account) setBalanceAction(a *Action) error { sg.MemberIds = make(utils.StringMap) } sg.MemberIds[acc.ID] = true - ratingStorage.SetSharedGroup(sg) + ratingStorage.SetSharedGroup(sg, utils.NonTransactional) } } } @@ -225,7 +225,7 @@ func (ub *Account) debitBalanceAction(a *Action, reset bool) error { _, err := Guardian.Guard(func() (interface{}, error) { for sgId := range bClone.SharedGroups { // add shared group member - sg, err := ratingStorage.GetSharedGroup(sgId, false) + sg, err := ratingStorage.GetSharedGroup(sgId, false, utils.NonTransactional) if err != nil || sg == nil { //than is problem utils.Logger.Warning(fmt.Sprintf("Could not get shared group: %v", sgId)) @@ -236,7 +236,7 @@ func (ub *Account) debitBalanceAction(a *Action, reset bool) error { sg.MemberIds = make(utils.StringMap) } sg.MemberIds[ub.ID] = true - ratingStorage.SetSharedGroup(sg) + ratingStorage.SetSharedGroup(sg, utils.NonTransactional) } } } @@ -306,7 +306,7 @@ func (ub *Account) getBalancesForPrefix(prefix, category, direction, tor string, if len(b.DestinationIDs) > 0 && b.DestinationIDs[utils.ANY] == false { for _, p := range utils.SplitPrefix(prefix, MIN_PREFIX_MATCH) { - if destIDs, err := ratingStorage.GetReverseDestination(p, false); err == nil { + if destIDs, err := ratingStorage.GetReverseDestination(p, false, utils.NonTransactional); err == nil { foundResult := false allInclude := true // whether it is excluded or included for _, dId := range destIDs { @@ -356,7 +356,7 @@ func (account *Account) getAlldBalancesForPrefix(destination, category, directio for _, b := range balances { if len(b.SharedGroups) > 0 { for sgId := range b.SharedGroups { - sharedGroup, err := ratingStorage.GetSharedGroup(sgId, false) + sharedGroup, err := ratingStorage.GetSharedGroup(sgId, false, utils.NonTransactional) if err != nil || sharedGroup == nil { utils.Logger.Warning(fmt.Sprintf("Could not get shared group: %v", sgId)) continue @@ -775,7 +775,7 @@ func (account *Account) GetUniqueSharedGroupMembers(cd *CallDescriptor) (utils.S } memberIds := make(utils.StringMap) for _, sgID := range sharedGroupIds { - sharedGroup, err := ratingStorage.GetSharedGroup(sgID, false) + sharedGroup, err := ratingStorage.GetSharedGroup(sgID, false, utils.NonTransactional) if err != nil { utils.Logger.Warning(fmt.Sprintf("Could not get shared group: %v", sgID)) return nil, err diff --git a/engine/account_test.go b/engine/account_test.go index 79609a0fa..ca9e0af04 100644 --- a/engine/account_test.go +++ b/engine/account_test.go @@ -1249,7 +1249,7 @@ func TestDebitShared(t *testing.T) { sg := &SharedGroup{Id: "SG_TEST", MemberIds: utils.NewStringMap(rif.ID, groupie.ID), AccountParameters: map[string]*SharingParameters{"*any": &SharingParameters{Strategy: STRATEGY_MINE_RANDOM}}} accountingStorage.SetAccount(groupie) - ratingStorage.SetSharedGroup(sg) + ratingStorage.SetSharedGroup(sg, utils.NonTransactional) cc, err := rif.debitCreditBalance(cd, false, false, true) if err != nil { t.Error("Error debiting balance: ", err) @@ -1318,7 +1318,7 @@ func TestMaxDurationShared(t *testing.T) { sg := &SharedGroup{Id: "SG_TEST", MemberIds: utils.NewStringMap(rif.ID, groupie.ID), AccountParameters: map[string]*SharingParameters{"*any": &SharingParameters{Strategy: STRATEGY_MINE_RANDOM}}} accountingStorage.SetAccount(groupie) - ratingStorage.SetSharedGroup(sg) + ratingStorage.SetSharedGroup(sg, utils.NonTransactional) duration, err := cd.getMaxSessionDuration(rif) if err != nil { t.Error("Error getting max session duration from shared group: ", err) diff --git a/engine/action.go b/engine/action.go index 898042a43..1c1ac0660 100644 --- a/engine/action.go +++ b/engine/action.go @@ -518,12 +518,12 @@ func setddestinations(ub *Account, sq *StatsQueueTriggered, a *Action, acs Actio i++ } newDest := &Destination{Id: ddcDestId, Prefixes: prefixes} - oldDest, err := ratingStorage.GetDestination(ddcDestId, false) + oldDest, err := ratingStorage.GetDestination(ddcDestId, false, utils.NonTransactional) // update destid in storage - ratingStorage.SetDestination(newDest) + ratingStorage.SetDestination(newDest, utils.NonTransactional) if err == nil && oldDest != nil { - err = ratingStorage.UpdateReverseDestination(oldDest, newDest) + err = ratingStorage.UpdateReverseDestination(oldDest, newDest, utils.NonTransactional) if err != nil { return err } @@ -569,7 +569,7 @@ func removeAccountAction(ub *Account, sq *StatsQueueTriggered, a *Action, acs Ac if _, exists := ap.AccountIDs[accID]; !exists { // save action plan delete(ap.AccountIDs, key) - ratingStorage.SetActionPlan(key, ap, true) + ratingStorage.SetActionPlan(key, ap, true, utils.NonTransactional) //dirtyAps = append(dirtyAps, utils.ACTION_PLAN_PREFIX+key) } } diff --git a/engine/action_plan.go b/engine/action_plan.go index cf6b82219..857573eef 100644 --- a/engine/action_plan.go +++ b/engine/action_plan.go @@ -268,7 +268,7 @@ func (at *ActionTiming) GetActionPlanID() string { func (at *ActionTiming) getActions() (as []*Action, err error) { if at.actions == nil { - at.actions, err = ratingStorage.GetActions(at.ActionsID, false) + at.actions, err = ratingStorage.GetActions(at.ActionsID, false, utils.NonTransactional) } at.actions.Sort() return at.actions, err diff --git a/engine/action_trigger.go b/engine/action_trigger.go index 4ff7a94ac..145d2bad0 100644 --- a/engine/action_trigger.go +++ b/engine/action_trigger.go @@ -57,7 +57,7 @@ func (at *ActionTrigger) Execute(ub *Account, sq *StatsQueueTriggered) (err erro } // does NOT need to Lock() because it is triggered from a method that took the Lock var aac Actions - aac, err = ratingStorage.GetActions(at.ActionsID, false) + aac, err = ratingStorage.GetActions(at.ActionsID, false, utils.NonTransactional) if err != nil { utils.Logger.Err(fmt.Sprintf("Failed to get actions: %v", err)) return diff --git a/engine/actions_test.go b/engine/actions_test.go index 2c2080274..5f0f6c994 100644 --- a/engine/actions_test.go +++ b/engine/actions_test.go @@ -1056,7 +1056,7 @@ func TestActionTriggerLogging(t *testing.T) { Weight: 10.0, ActionsID: "TEST_ACTIONS", } - as, err := ratingStorage.GetActions(at.ActionsID, false) + as, err := ratingStorage.GetActions(at.ActionsID, false, utils.NonTransactional) if err != nil { t.Error("Error getting actions for the action timing: ", as, err) } @@ -1286,24 +1286,24 @@ func TestActionCdrLogParamsWithOverload(t *testing.T) { func TestActionSetDDestination(t *testing.T) { acc := &Account{BalanceMap: map[string]Balances{utils.MONETARY: Balances{&Balance{DestinationIDs: utils.NewStringMap("*ddc_test")}}}} origD := &Destination{Id: "*ddc_test", Prefixes: []string{"111", "222"}} - ratingStorage.SetDestination(origD) - ratingStorage.SetReverseDestination(origD) + ratingStorage.SetDestination(origD, utils.NonTransactional) + ratingStorage.SetReverseDestination(origD, utils.NonTransactional) // check redis and cache - if d, err := ratingStorage.GetDestination("*ddc_test", false); err != nil || !reflect.DeepEqual(d, origD) { + if d, err := ratingStorage.GetDestination("*ddc_test", false, utils.NonTransactional); err != nil || !reflect.DeepEqual(d, origD) { t.Error("Error storing destination: ", d, err) } - ratingStorage.GetReverseDestination("111", false) + ratingStorage.GetReverseDestination("111", false, utils.NonTransactional) x1, found := cache2go.Get(utils.REVERSE_DESTINATION_PREFIX + "111") if !found || len(x1.([]string)) != 1 { t.Error("Error cacheing destination: ", x1) } - ratingStorage.GetReverseDestination("222", false) + ratingStorage.GetReverseDestination("222", false, utils.NonTransactional) x1, found = cache2go.Get(utils.REVERSE_DESTINATION_PREFIX + "222") if !found || len(x1.([]string)) != 1 { t.Error("Error cacheing destination: ", x1) } setddestinations(acc, &StatsQueueTriggered{Metrics: map[string]float64{"333": 1, "666": 1}}, nil, nil) - d, err := ratingStorage.GetDestination("*ddc_test", false) + d, err := ratingStorage.GetDestination("*ddc_test", false, utils.NonTransactional) if err != nil || d.Id != origD.Id || len(d.Prefixes) != 2 || @@ -1321,12 +1321,12 @@ func TestActionSetDDestination(t *testing.T) { if ok { t.Error("Error cacheing destination: ", x1) } - ratingStorage.GetReverseDestination("333", false) + ratingStorage.GetReverseDestination("333", false, utils.NonTransactional) x1, found = cache2go.Get(utils.REVERSE_DESTINATION_PREFIX + "333") if !found || len(x1.([]string)) != 1 { t.Error("Error cacheing destination: ", x1) } - ratingStorage.GetReverseDestination("666", false) + ratingStorage.GetReverseDestination("666", false, utils.NonTransactional) x1, found = cache2go.Get(utils.REVERSE_DESTINATION_PREFIX + "666") if !found || len(x1.([]string)) != 1 { t.Error("Error cacheing destination: ", x1) @@ -2063,7 +2063,7 @@ func TestActionSetBalance(t *testing.T) { } func TestActionCSVFilter(t *testing.T) { - act, err := ratingStorage.GetActions("FILTER", false) + act, err := ratingStorage.GetActions("FILTER", false, utils.NonTransactional) if err != nil { t.Error("error getting actions: ", err) } @@ -2073,7 +2073,7 @@ func TestActionCSVFilter(t *testing.T) { } func TestActionExpirationTime(t *testing.T) { - a, err := ratingStorage.GetActions("EXP", false) + a, err := ratingStorage.GetActions("EXP", false, utils.NonTransactional) if err != nil || a == nil { t.Error("Error getting actions: ", err) } @@ -2093,11 +2093,11 @@ func TestActionExpirationTime(t *testing.T) { } func TestActionExpNoExp(t *testing.T) { - exp, err := ratingStorage.GetActions("EXP", false) + exp, err := ratingStorage.GetActions("EXP", false, utils.NonTransactional) if err != nil || exp == nil { t.Error("Error getting actions: ", err) } - noexp, err := ratingStorage.GetActions("NOEXP", false) + noexp, err := ratingStorage.GetActions("NOEXP", false, utils.NonTransactional) if err != nil || noexp == nil { t.Error("Error getting actions: ", err) } diff --git a/engine/aliases.go b/engine/aliases.go index 5f99eabba..4d175bdc6 100644 --- a/engine/aliases.go +++ b/engine/aliases.go @@ -165,15 +165,15 @@ func (am *AliasHandler) SetAlias(attr *AttrAddAlias, reply *string) error { var oldAlias *Alias if !attr.Overwrite { // get previous value - oldAlias, _ = am.accountingDb.GetAlias(attr.Alias.GetId(), false) + oldAlias, _ = am.accountingDb.GetAlias(attr.Alias.GetId(), false, utils.NonTransactional) } if attr.Overwrite || oldAlias == nil { - if err := am.accountingDb.SetAlias(attr.Alias); err != nil { + if err := am.accountingDb.SetAlias(attr.Alias, utils.NonTransactional); err != nil { *reply = err.Error() return err } - if err := am.accountingDb.SetReverseAlias(attr.Alias); err != nil { + if err := am.accountingDb.SetReverseAlias(attr.Alias, utils.NonTransactional); err != nil { *reply = err.Error() return err } @@ -202,11 +202,11 @@ func (am *AliasHandler) SetAlias(attr *AttrAddAlias, reply *string) error { oldAlias.Values = append(oldAlias.Values, value) } } - if err := am.accountingDb.SetAlias(oldAlias); err != nil { + if err := am.accountingDb.SetAlias(oldAlias, utils.NonTransactional); err != nil { *reply = err.Error() return err } - if err := am.accountingDb.SetReverseAlias(oldAlias); err != nil { + if err := am.accountingDb.SetReverseAlias(oldAlias, utils.NonTransactional); err != nil { *reply = err.Error() return err } @@ -224,7 +224,7 @@ func (am *AliasHandler) SetAlias(attr *AttrAddAlias, reply *string) error { func (am *AliasHandler) RemoveAlias(al *Alias, reply *string) error { am.mu.Lock() defer am.mu.Unlock() - if err := am.accountingDb.RemoveAlias(al.GetId()); err != nil { + if err := am.accountingDb.RemoveAlias(al.GetId(), utils.NonTransactional); err != nil { *reply = err.Error() return err } @@ -237,7 +237,7 @@ func (am *AliasHandler) GetAlias(al *Alias, result *Alias) error { defer am.mu.RUnlock() variants := al.GenerateIds() for _, variant := range variants { - if r, err := am.accountingDb.GetAlias(variant, false); err == nil { + if r, err := am.accountingDb.GetAlias(variant, false, utils.NonTransactional); err == nil { *result = *r return nil } @@ -250,7 +250,7 @@ func (am *AliasHandler) GetReverseAlias(attr *AttrReverseAlias, result *map[stri defer am.mu.Unlock() aliases := make(map[string][]*Alias) rKey := attr.Alias + attr.Target + attr.Context - if ids, err := am.accountingDb.GetReverseAlias(rKey, false); err == nil { + if ids, err := am.accountingDb.GetReverseAlias(rKey, false, utils.NonTransactional); err == nil { for _, key := range ids { // get destination id elems := strings.Split(key, utils.CONCATENATED_KEY_SEP) @@ -259,7 +259,7 @@ func (am *AliasHandler) GetReverseAlias(attr *AttrReverseAlias, result *map[stri destID = elems[len(elems)-1] key = strings.Join(elems[:len(elems)-1], utils.CONCATENATED_KEY_SEP) } - if r, err := am.accountingDb.GetAlias(key, false); err != nil { + if r, err := am.accountingDb.GetAlias(key, false, utils.NonTransactional); err != nil { return err } else { aliases[destID] = append(aliases[destID], r) @@ -300,7 +300,7 @@ func (am *AliasHandler) GetMatchingAlias(attr *AttrMatchingAlias, result *string } // check destination ids for _, p := range utils.SplitPrefix(attr.Destination, MIN_PREFIX_MATCH) { - if destIDs, err := ratingStorage.GetReverseDestination(p, false); err == nil { + if destIDs, err := ratingStorage.GetReverseDestination(p, false, utils.NonTransactional); err == nil { for _, value := range values { for _, dId := range destIDs { if value.DestinationId == utils.ANY || value.DestinationId == dId { @@ -379,7 +379,7 @@ func LoadAlias(attr *AttrMatchingAlias, in interface{}, extraFields string) erro if rightPairs == nil { // check destination ids for _, p := range utils.SplitPrefix(attr.Destination, MIN_PREFIX_MATCH) { - if destIDs, err := ratingStorage.GetReverseDestination(p, false); err == nil { + if destIDs, err := ratingStorage.GetReverseDestination(p, false, utils.NonTransactional); err == nil { for _, value := range values { for _, dId := range destIDs { if value.DestinationId == utils.ANY || value.DestinationId == dId { diff --git a/engine/aliases_test.go b/engine/aliases_test.go index a2b2164f6..1fb8d6972 100644 --- a/engine/aliases_test.go +++ b/engine/aliases_test.go @@ -208,7 +208,7 @@ func TestAliasesLoadAlias(t *testing.T) { func TestAliasesCache(t *testing.T) { key := "*out:cgrates.org:call:remo:remo:*rating" - _, err := accountingStorage.GetAlias(key, false) + _, err := accountingStorage.GetAlias(key, false, utils.NonTransactional) if err != nil { t.Error("Error getting alias: ", err) } @@ -218,7 +218,7 @@ func TestAliasesCache(t *testing.T) { t.Error("Error getting alias from cache: ", err, a) } rKey1 := "minuAccount*rating" - _, err = accountingStorage.GetReverseAlias(rKey1, false) + _, err = accountingStorage.GetReverseAlias(rKey1, false, utils.NonTransactional) if err != nil { t.Error("Error getting reverse alias: ", err) } @@ -227,7 +227,7 @@ func TestAliasesCache(t *testing.T) { t.Error("Error getting reverse alias 1: ", ra1) } rKey2 := "minuSubject*rating" - _, err = accountingStorage.GetReverseAlias(rKey2, false) + _, err = accountingStorage.GetReverseAlias(rKey2, false, utils.NonTransactional) if err != nil { t.Error("Error getting reverse alias: ", err) } @@ -235,12 +235,12 @@ func TestAliasesCache(t *testing.T) { if !found || len(ra2.([]string)) != 2 { t.Error("Error getting reverse alias 2: ", ra2) } - accountingStorage.RemoveAlias(key) + accountingStorage.RemoveAlias(key, utils.NonTransactional) a, found = cache2go.Get(utils.ALIASES_PREFIX + key) if found { t.Error("Error getting alias from cache: ", found) } - _, err = accountingStorage.GetReverseAlias(rKey1, false) + _, err = accountingStorage.GetReverseAlias(rKey1, false, utils.NonTransactional) if err != nil { t.Error("Error getting reverse alias: ", err) } @@ -248,7 +248,7 @@ func TestAliasesCache(t *testing.T) { if !found || len(ra1.([]string)) != 1 { t.Error("Error getting reverse alias 1: ", ra1) } - _, err = accountingStorage.GetReverseAlias(rKey2, false) + _, err = accountingStorage.GetReverseAlias(rKey2, false, utils.NonTransactional) if err != nil { t.Error("Error getting reverse alias: ", err) } diff --git a/engine/balances.go b/engine/balances.go index 5da03ec59..3b259ec8b 100644 --- a/engine/balances.go +++ b/engine/balances.go @@ -195,7 +195,7 @@ func (b *Balance) Clone() *Balance { func (b *Balance) getMatchingPrefixAndDestID(dest string) (prefix, destId string) { if len(b.DestinationIDs) != 0 && b.DestinationIDs[utils.ANY] == false { for _, p := range utils.SplitPrefix(dest, MIN_PREFIX_MATCH) { - if destIDs, err := ratingStorage.GetReverseDestination(p, false); err == nil { + if destIDs, err := ratingStorage.GetReverseDestination(p, false, utils.NonTransactional); err == nil { for _, dID := range destIDs { if b.DestinationIDs[dID] == true { return p, dID diff --git a/engine/callcost.go b/engine/callcost.go index 97bf4e780..4e9189690 100644 --- a/engine/callcost.go +++ b/engine/callcost.go @@ -235,7 +235,7 @@ func (cc *CallCost) MatchCCFilter(bf *BalanceFilter) bool { foundMatchingDestID := false if bf.DestinationIDs != nil && cc.Destination != "" { for _, p := range utils.SplitPrefix(cc.Destination, MIN_PREFIX_MATCH) { - if destIDs, err := ratingStorage.GetReverseDestination(p, false); err == nil { + if destIDs, err := ratingStorage.GetReverseDestination(p, false, utils.NonTransactional); err == nil { for _, dID := range destIDs { if _, ok := (*bf.DestinationIDs)[dID]; ok { foundMatchingDestID = true diff --git a/engine/calldesc.go b/engine/calldesc.go index c68588ade..2ebbcf19b 100644 --- a/engine/calldesc.go +++ b/engine/calldesc.go @@ -952,7 +952,7 @@ func (cd *CallDescriptor) GetLCRFromStorage() (*LCR, error) { keyVariants = append(keyVariants[:1], append(partialSubjects, keyVariants[1:]...)...) } for _, key := range keyVariants { - if lcr, err := ratingStorage.GetLCR(key, false); err != nil && err != utils.ErrNotFound { + if lcr, err := ratingStorage.GetLCR(key, false, utils.NonTransactional); err != nil && err != utils.ErrNotFound { return nil, err } else if err == nil { return lcr, nil diff --git a/engine/calldesc_test.go b/engine/calldesc_test.go index ba4177089..3f39c9971 100644 --- a/engine/calldesc_test.go +++ b/engine/calldesc_test.go @@ -102,8 +102,8 @@ func populateDB() { }}, } if accountingStorage != nil && ratingStorage != nil { - ratingStorage.SetActions("TEST_ACTIONS", ats) - ratingStorage.SetActions("TEST_ACTIONS_ORDER", ats1) + ratingStorage.SetActions("TEST_ACTIONS", ats, utils.NonTransactional) + ratingStorage.SetActions("TEST_ACTIONS_ORDER", ats1, utils.NonTransactional) accountingStorage.SetAccount(broker) accountingStorage.SetAccount(minu) accountingStorage.SetAccount(minitsboy) @@ -554,7 +554,7 @@ func TestMaxSessionTimeWithAccount(t *testing.T) { } func TestMaxSessionTimeWithMaxRate(t *testing.T) { - ap, err := ratingStorage.GetActionPlan("TOPUP10_AT", false) + ap, err := ratingStorage.GetActionPlan("TOPUP10_AT", false, utils.NonTransactional) if err != nil { t.FailNow() } @@ -585,7 +585,7 @@ func TestMaxSessionTimeWithMaxRate(t *testing.T) { } func TestMaxSessionTimeWithMaxCost(t *testing.T) { - ap, _ := ratingStorage.GetActionPlan("TOPUP10_AT", false) + ap, _ := ratingStorage.GetActionPlan("TOPUP10_AT", false, utils.NonTransactional) for _, at := range ap.ActionTimings { at.accountIDs = ap.AccountIDs at.Execute() @@ -609,7 +609,7 @@ func TestMaxSessionTimeWithMaxCost(t *testing.T) { } func TestGetMaxSessiontWithBlocker(t *testing.T) { - ap, _ := ratingStorage.GetActionPlan("BLOCK_AT", false) + ap, _ := ratingStorage.GetActionPlan("BLOCK_AT", false, utils.NonTransactional) for _, at := range ap.ActionTimings { at.accountIDs = ap.AccountIDs at.Execute() @@ -660,7 +660,7 @@ func TestGetMaxSessiontWithBlocker(t *testing.T) { } func TestGetMaxSessiontWithBlockerEmpty(t *testing.T) { - ap, _ := ratingStorage.GetActionPlan("BLOCK_EMPTY_AT", false) + ap, _ := ratingStorage.GetActionPlan("BLOCK_EMPTY_AT", false, utils.NonTransactional) for _, at := range ap.ActionTimings { at.accountIDs = ap.AccountIDs at.Execute() @@ -711,7 +711,7 @@ func TestGetMaxSessiontWithBlockerEmpty(t *testing.T) { } func TestGetCostWithMaxCost(t *testing.T) { - ap, _ := ratingStorage.GetActionPlan("TOPUP10_AT", false) + ap, _ := ratingStorage.GetActionPlan("TOPUP10_AT", false, utils.NonTransactional) for _, at := range ap.ActionTimings { at.accountIDs = ap.AccountIDs at.Execute() @@ -735,7 +735,7 @@ func TestGetCostWithMaxCost(t *testing.T) { } func TestGetCostRoundingIssue(t *testing.T) { - ap, _ := ratingStorage.GetActionPlan("TOPUP10_AT", false) + ap, _ := ratingStorage.GetActionPlan("TOPUP10_AT", false, utils.NonTransactional) for _, at := range ap.ActionTimings { at.accountIDs = ap.AccountIDs at.Execute() @@ -760,7 +760,7 @@ func TestGetCostRoundingIssue(t *testing.T) { } func TestGetCostRatingInfoOnZeroTime(t *testing.T) { - ap, _ := ratingStorage.GetActionPlan("TOPUP10_AT", false) + ap, _ := ratingStorage.GetActionPlan("TOPUP10_AT", false, utils.NonTransactional) for _, at := range ap.ActionTimings { at.accountIDs = ap.AccountIDs at.Execute() @@ -788,7 +788,7 @@ func TestGetCostRatingInfoOnZeroTime(t *testing.T) { } func TestDebitRatingInfoOnZeroTime(t *testing.T) { - ap, _ := ratingStorage.GetActionPlan("TOPUP10_AT", false) + ap, _ := ratingStorage.GetActionPlan("TOPUP10_AT", false, utils.NonTransactional) for _, at := range ap.ActionTimings { at.accountIDs = ap.AccountIDs at.Execute() @@ -817,7 +817,7 @@ func TestDebitRatingInfoOnZeroTime(t *testing.T) { } func TestMaxDebitRatingInfoOnZeroTime(t *testing.T) { - ap, _ := ratingStorage.GetActionPlan("TOPUP10_AT", false) + ap, _ := ratingStorage.GetActionPlan("TOPUP10_AT", false, utils.NonTransactional) for _, at := range ap.ActionTimings { at.accountIDs = ap.AccountIDs at.Execute() @@ -845,7 +845,7 @@ func TestMaxDebitRatingInfoOnZeroTime(t *testing.T) { } func TestMaxDebitUnknowDest(t *testing.T) { - ap, _ := ratingStorage.GetActionPlan("TOPUP10_AT", false) + ap, _ := ratingStorage.GetActionPlan("TOPUP10_AT", false, utils.NonTransactional) for _, at := range ap.ActionTimings { at.accountIDs = ap.AccountIDs at.Execute() @@ -868,7 +868,7 @@ func TestMaxDebitUnknowDest(t *testing.T) { } func TestMaxDebitRoundingIssue(t *testing.T) { - ap, _ := ratingStorage.GetActionPlan("TOPUP10_AT", false) + ap, _ := ratingStorage.GetActionPlan("TOPUP10_AT", false, utils.NonTransactional) for _, at := range ap.ActionTimings { at.accountIDs = ap.AccountIDs at.Execute() @@ -903,7 +903,7 @@ func TestMaxDebitRoundingIssue(t *testing.T) { } func TestDebitRoundingRefund(t *testing.T) { - ap, _ := ratingStorage.GetActionPlan("TOPUP10_AT", false) + ap, _ := ratingStorage.GetActionPlan("TOPUP10_AT", false, utils.NonTransactional) for _, at := range ap.ActionTimings { at.accountIDs = ap.AccountIDs at.Execute() @@ -938,7 +938,7 @@ func TestDebitRoundingRefund(t *testing.T) { } func TestMaxSessionTimeWithMaxCostFree(t *testing.T) { - ap, _ := ratingStorage.GetActionPlan("TOPUP10_AT", false) + ap, _ := ratingStorage.GetActionPlan("TOPUP10_AT", false, utils.NonTransactional) for _, at := range ap.ActionTimings { at.accountIDs = ap.AccountIDs at.Execute() @@ -962,7 +962,7 @@ func TestMaxSessionTimeWithMaxCostFree(t *testing.T) { } func TestMaxDebitWithMaxCostFree(t *testing.T) { - ap, _ := ratingStorage.GetActionPlan("TOPUP10_AT", false) + ap, _ := ratingStorage.GetActionPlan("TOPUP10_AT", false, utils.NonTransactional) for _, at := range ap.ActionTimings { at.accountIDs = ap.AccountIDs at.Execute() @@ -986,7 +986,7 @@ func TestMaxDebitWithMaxCostFree(t *testing.T) { } func TestGetCostWithMaxCostFree(t *testing.T) { - ap, _ := ratingStorage.GetActionPlan("TOPUP10_AT", false) + ap, _ := ratingStorage.GetActionPlan("TOPUP10_AT", false, utils.NonTransactional) for _, at := range ap.ActionTimings { at.accountIDs = ap.AccountIDs at.Execute() @@ -1041,12 +1041,12 @@ func TestMaxSessionTimeWithAccountAlias(t *testing.T) { } func TestMaxSessionTimeWithAccountShared(t *testing.T) { - ap, _ := ratingStorage.GetActionPlan("TOPUP_SHARED0_AT", false) + ap, _ := ratingStorage.GetActionPlan("TOPUP_SHARED0_AT", false, utils.NonTransactional) for _, at := range ap.ActionTimings { at.accountIDs = ap.AccountIDs at.Execute() } - ap, _ = ratingStorage.GetActionPlan("TOPUP_SHARED10_AT", false) + ap, _ = ratingStorage.GetActionPlan("TOPUP_SHARED10_AT", false, utils.NonTransactional) for _, at := range ap.ActionTimings { at.accountIDs = ap.AccountIDs at.Execute() @@ -1082,12 +1082,12 @@ func TestMaxSessionTimeWithAccountShared(t *testing.T) { } func TestMaxDebitWithAccountShared(t *testing.T) { - ap, _ := ratingStorage.GetActionPlan("TOPUP_SHARED0_AT", false) + ap, _ := ratingStorage.GetActionPlan("TOPUP_SHARED0_AT", false, utils.NonTransactional) for _, at := range ap.ActionTimings { at.accountIDs = ap.AccountIDs at.Execute() } - ap, _ = ratingStorage.GetActionPlan("TOPUP_SHARED10_AT", false) + ap, _ = ratingStorage.GetActionPlan("TOPUP_SHARED10_AT", false, utils.NonTransactional) for _, at := range ap.ActionTimings { at.accountIDs = ap.AccountIDs at.Execute() @@ -1305,7 +1305,7 @@ func TestMaxSesionTimeLongerThanMoney(t *testing.T) { } func TestDebitFromShareAndNormal(t *testing.T) { - ap, _ := ratingStorage.GetActionPlan("TOPUP_SHARED10_AT", false) + ap, _ := ratingStorage.GetActionPlan("TOPUP_SHARED10_AT", false, utils.NonTransactional) for _, at := range ap.ActionTimings { at.accountIDs = ap.AccountIDs at.Execute() @@ -1334,7 +1334,7 @@ func TestDebitFromShareAndNormal(t *testing.T) { } func TestDebitFromEmptyShare(t *testing.T) { - ap, _ := ratingStorage.GetActionPlan("TOPUP_EMPTY_AT", false) + ap, _ := ratingStorage.GetActionPlan("TOPUP_EMPTY_AT", false, utils.NonTransactional) for _, at := range ap.ActionTimings { at.accountIDs = ap.AccountIDs at.Execute() @@ -1363,7 +1363,7 @@ func TestDebitFromEmptyShare(t *testing.T) { } func TestDebitNegatve(t *testing.T) { - ap, _ := ratingStorage.GetActionPlan("POST_AT", false) + ap, _ := ratingStorage.GetActionPlan("POST_AT", false, utils.NonTransactional) for _, at := range ap.ActionTimings { at.accountIDs = ap.AccountIDs at.Execute() @@ -1403,7 +1403,7 @@ func TestDebitNegatve(t *testing.T) { } func TestMaxDebitZeroDefinedRate(t *testing.T) { - ap, _ := ratingStorage.GetActionPlan("TOPUP10_AT", false) + ap, _ := ratingStorage.GetActionPlan("TOPUP10_AT", false, utils.NonTransactional) for _, at := range ap.ActionTimings { at.accountIDs = ap.AccountIDs at.Execute() @@ -1432,7 +1432,7 @@ func TestMaxDebitZeroDefinedRate(t *testing.T) { } func TestMaxDebitForceDuration(t *testing.T) { - ap, _ := ratingStorage.GetActionPlan("TOPUP10_AT", false) + ap, _ := ratingStorage.GetActionPlan("TOPUP10_AT", false, utils.NonTransactional) for _, at := range ap.ActionTimings { at.accountIDs = ap.AccountIDs at.Execute() @@ -1457,7 +1457,7 @@ func TestMaxDebitForceDuration(t *testing.T) { } func TestMaxDebitZeroDefinedRateOnlyMinutes(t *testing.T) { - ap, _ := ratingStorage.GetActionPlan("TOPUP10_AT", false) + ap, _ := ratingStorage.GetActionPlan("TOPUP10_AT", false, utils.NonTransactional) for _, at := range ap.ActionTimings { at.accountIDs = ap.AccountIDs at.Execute() @@ -1486,7 +1486,7 @@ func TestMaxDebitZeroDefinedRateOnlyMinutes(t *testing.T) { } func TestMaxDebitConsumesMinutes(t *testing.T) { - ap, _ := ratingStorage.GetActionPlan("TOPUP10_AT", false) + ap, _ := ratingStorage.GetActionPlan("TOPUP10_AT", false, utils.NonTransactional) for _, at := range ap.ActionTimings { at.accountIDs = ap.AccountIDs at.Execute() @@ -1628,7 +1628,7 @@ func BenchmarkStorageGetting(b *testing.B) { cd := &CallDescriptor{Direction: "*out", Category: "0", Tenant: "vdf", Subject: "rif", Destination: "0256", TimeStart: t1, TimeEnd: t2} b.StartTimer() for i := 0; i < b.N; i++ { - ratingStorage.GetRatingProfile(cd.GetKey(cd.Subject), false) + ratingStorage.GetRatingProfile(cd.GetKey(cd.Subject), false, utils.NonTransactional) } } diff --git a/engine/cdrstats.go b/engine/cdrstats.go index c8a88b6c6..632c64865 100644 --- a/engine/cdrstats.go +++ b/engine/cdrstats.go @@ -123,7 +123,7 @@ func (cs *CdrStats) AcceptCdr(cdr *CDR) bool { if len(cs.DestinationIds) > 0 { found := false for _, p := range utils.SplitPrefix(cdr.Destination, MIN_PREFIX_MATCH) { - if destIDs, err := ratingStorage.GetReverseDestination(p, false); err == nil { + if destIDs, err := ratingStorage.GetReverseDestination(p, false, utils.NonTransactional); err == nil { for _, idID := range destIDs { if utils.IsSliceMember(cs.DestinationIds, idID) { found = true diff --git a/engine/destinations.go b/engine/destinations.go index 52fa5f13f..47f6bd556 100644 --- a/engine/destinations.go +++ b/engine/destinations.go @@ -74,7 +74,7 @@ func (d *Destination) GetHistoryRecord(deleted bool) history.Record { // Reverse search in cache to see if prefix belongs to destination id func CachedDestHasPrefix(destId, prefix string) bool { - if cached, err := ratingStorage.GetReverseDestination(prefix, true); err == nil { + if cached, err := ratingStorage.GetReverseDestination(prefix, true, utils.NonTransactional); err == nil { return utils.IsSliceMember(cached, destId) } return false diff --git a/engine/destinations_test.go b/engine/destinations_test.go index 6d2747a1a..4525f08ad 100644 --- a/engine/destinations_test.go +++ b/engine/destinations_test.go @@ -40,11 +40,11 @@ func TestDestinationStoreRestore(t *testing.T) { func TestDestinationStorageStore(t *testing.T) { nationale := &Destination{Id: "nat", Prefixes: []string{"0257", "0256", "0723"}} - err := ratingStorage.SetDestination(nationale) + err := ratingStorage.SetDestination(nationale, utils.NonTransactional) if err != nil { t.Error("Error storing destination: ", err) } - result, err := ratingStorage.GetDestination(nationale.Id, false) + result, err := ratingStorage.GetDestination(nationale.Id, false, utils.NonTransactional) if nationale.containsPrefix("0257") == 0 || nationale.containsPrefix("0256") == 0 || nationale.containsPrefix("0723") == 0 { t.Errorf("Expected %q was %q", nationale, result) } @@ -75,28 +75,28 @@ func TestDestinationContainsPrefixWrong(t *testing.T) { } func TestDestinationGetExists(t *testing.T) { - d, err := ratingStorage.GetDestination("NAT", false) + d, err := ratingStorage.GetDestination("NAT", false, utils.NonTransactional) if err != nil || d == nil { t.Error("Could not get destination: ", d) } } func TestDestinationReverseGetExistsCache(t *testing.T) { - ratingStorage.GetReverseDestination("0256", false) + ratingStorage.GetReverseDestination("0256", false, utils.NonTransactional) if _, ok := cache2go.Get(utils.REVERSE_DESTINATION_PREFIX + "0256"); !ok { t.Error("Destination not cached:", err) } } func TestDestinationGetNotExists(t *testing.T) { - d, err := ratingStorage.GetDestination("not existing", false) + d, err := ratingStorage.GetDestination("not existing", false, utils.NonTransactional) if d != nil { t.Error("Got false destination: ", d, err) } } func TestDestinationGetNotExistsCache(t *testing.T) { - ratingStorage.GetDestination("not existing", false) + ratingStorage.GetDestination("not existing", false, utils.NonTransactional) if d, ok := cache2go.Get("not existing"); ok { t.Error("Bad destination cached: ", d) } @@ -149,7 +149,7 @@ func TestCleanStalePrefixes(t *testing.T) { func BenchmarkDestinationStorageStoreRestore(b *testing.B) { nationale := &Destination{Id: "nat", Prefixes: []string{"0257", "0256", "0723"}} for i := 0; i < b.N; i++ { - ratingStorage.SetDestination(nationale) - ratingStorage.GetDestination(nationale.Id, true) + ratingStorage.SetDestination(nationale, utils.NonTransactional) + ratingStorage.GetDestination(nationale.Id, true, utils.NonTransactional) } } diff --git a/engine/handler_derivedcharging.go b/engine/handler_derivedcharging.go index 86c956a9a..4cea2eab6 100644 --- a/engine/handler_derivedcharging.go +++ b/engine/handler_derivedcharging.go @@ -29,7 +29,7 @@ func HandleGetDerivedChargers(ratingStorage RatingStorage, attrs *utils.AttrDeri anyCategKey := utils.DerivedChargersKey(attrs.Direction, attrs.Tenant, utils.ANY, utils.ANY, utils.ANY) anyTenantKey := utils.DerivedChargersKey(attrs.Direction, utils.ANY, utils.ANY, utils.ANY, utils.ANY) for _, dcKey := range []string{strictKey, anySubjKey, anyAcntKey, anyCategKey, anyTenantKey} { - if dcsDb, err := ratingStorage.GetDerivedChargers(dcKey, false); err != nil && err != utils.ErrNotFound { + if dcsDb, err := ratingStorage.GetDerivedChargers(dcKey, false, utils.NonTransactional); err != nil && err != utils.ErrNotFound { return nil, err } else if dcsDb != nil && DerivedChargersMatchesDest(dcsDb, attrs.Destination) { dcs = dcsDb @@ -45,7 +45,7 @@ func DerivedChargersMatchesDest(dcs *utils.DerivedChargers, dest string) bool { } // check destination ids for _, p := range utils.SplitPrefix(dest, MIN_PREFIX_MATCH) { - if destIDs, err := ratingStorage.GetReverseDestination(p, false); err == nil { + if destIDs, err := ratingStorage.GetReverseDestination(p, false, utils.NonTransactional); err == nil { for _, dId := range destIDs { includeDest, found := dcs.DestinationIDs[dId] if found { diff --git a/engine/lcr.go b/engine/lcr.go index ad18de12f..b3b7fd20c 100644 --- a/engine/lcr.go +++ b/engine/lcr.go @@ -279,7 +279,7 @@ func (es LCREntriesSorter) Sort() { func (lcra *LCRActivation) GetLCREntryForPrefix(destination string) *LCREntry { var potentials LCREntriesSorter for _, p := range utils.SplitPrefix(destination, MIN_PREFIX_MATCH) { - if destIDs, err := ratingStorage.GetReverseDestination(p, true); err == nil { + if destIDs, err := ratingStorage.GetReverseDestination(p, true, utils.NonTransactional); err == nil { for _, dId := range destIDs { for _, entry := range lcra.Entries { if entry.DestinationId == dId { diff --git a/engine/ratingplan_test.go b/engine/ratingplan_test.go index cd45f9a7c..a8f659138 100644 --- a/engine/ratingplan_test.go +++ b/engine/ratingplan_test.go @@ -449,9 +449,9 @@ func BenchmarkRatingPlanRestore(b *testing.B) { EndTime: "15:00:00"}} rp := &RatingPlan{Id: "test"} rp.AddRateInterval("NAT", i) - ratingStorage.SetRatingPlan(rp) + ratingStorage.SetRatingPlan(rp, utils.NonTransactional) b.ResetTimer() for i := 0; i < b.N; i++ { - ratingStorage.GetRatingPlan(rp.Id, true) + ratingStorage.GetRatingPlan(rp.Id, true, utils.NonTransactional) } } diff --git a/engine/ratingprofile.go b/engine/ratingprofile.go index 41091567b..8145a1bc4 100644 --- a/engine/ratingprofile.go +++ b/engine/ratingprofile.go @@ -155,7 +155,7 @@ func (ris RatingInfos) String() string { func (rpf *RatingProfile) GetRatingPlansForPrefix(cd *CallDescriptor) (err error) { var ris RatingInfos for index, rpa := range rpf.RatingPlanActivations.GetActiveForCall(cd) { - rpl, err := ratingStorage.GetRatingPlan(rpa.RatingPlanId, false) + rpl, err := ratingStorage.GetRatingPlan(rpa.RatingPlanId, false, utils.NonTransactional) if err != nil || rpl == nil { utils.Logger.Err(fmt.Sprintf("Error checking destination: %v", err)) continue @@ -172,7 +172,7 @@ func (rpf *RatingProfile) GetRatingPlansForPrefix(cd *CallDescriptor) (err error } } else { for _, p := range utils.SplitPrefix(cd.Destination, MIN_PREFIX_MATCH) { - if destIDs, err := ratingStorage.GetReverseDestination(p, false); err == nil { + if destIDs, err := ratingStorage.GetReverseDestination(p, false, utils.NonTransactional); err == nil { var bestWeight float64 for _, dID := range destIDs { if _, ok := rpl.DestinationRates[dID]; ok { @@ -257,9 +257,9 @@ type TenantRatingSubject struct { func RatingProfileSubjectPrefixMatching(key string) (rp *RatingProfile, err error) { if !rpSubjectPrefixMatching || strings.HasSuffix(key, utils.ANY) { - return ratingStorage.GetRatingProfile(key, false) + return ratingStorage.GetRatingProfile(key, false, utils.NonTransactional) } - if rp, err = ratingStorage.GetRatingProfile(key, false); err == nil { + if rp, err = ratingStorage.GetRatingProfile(key, false, utils.NonTransactional); err == nil { return rp, err } lastIndex := strings.LastIndex(key, utils.CONCATENATED_KEY_SEP) @@ -267,7 +267,7 @@ func RatingProfileSubjectPrefixMatching(key string) (rp *RatingProfile, err erro subject := key[lastIndex:] lenSubject := len(subject) for i := 1; i < lenSubject-1; i++ { - if rp, err = ratingStorage.GetRatingProfile(baseKey+subject[:lenSubject-i], false); err == nil { + if rp, err = ratingStorage.GetRatingProfile(baseKey+subject[:lenSubject-i], false, utils.NonTransactional); err == nil { return rp, err } } diff --git a/engine/reqfilter.go b/engine/reqfilter.go index 5d97e3bea..d3bd0102a 100644 --- a/engine/reqfilter.go +++ b/engine/reqfilter.go @@ -168,7 +168,7 @@ func (fltr *RequestFilter) passDestinations(req interface{}, extraFieldsLabel st return false, err } for _, p := range utils.SplitPrefix(dst, MIN_PREFIX_MATCH) { - if destIDs, err := ratingStorage.GetReverseDestination(p, false); err == nil { + if destIDs, err := ratingStorage.GetReverseDestination(p, false, utils.NonTransactional); err == nil { for _, dID := range destIDs { for _, valDstID := range fltr.Values { if valDstID == dID { diff --git a/engine/reqfilter_test.go b/engine/reqfilter_test.go index d32681714..88c5a4d87 100644 --- a/engine/reqfilter_test.go +++ b/engine/reqfilter_test.go @@ -120,7 +120,7 @@ func TestPassRSRFields(t *testing.T) { } func TestPassDestinations(t *testing.T) { - cache2go.Set(utils.REVERSE_DESTINATION_PREFIX+"+49", []string{"DE", "EU_LANDLINE"}) + cache2go.Set(utils.REVERSE_DESTINATION_PREFIX+"+49", []string{"DE", "EU_LANDLINE"}, true, "") cd := &CallDescriptor{Direction: "*out", Category: "call", Tenant: "cgrates.org", Subject: "dan", Destination: "+4986517174963", TimeStart: time.Date(2013, time.October, 7, 14, 50, 0, 0, time.UTC), TimeEnd: time.Date(2013, time.October, 7, 14, 52, 12, 0, time.UTC), DurationIndex: 132 * time.Second, ExtraFields: map[string]string{"navigation": "off"}} diff --git a/engine/reslimiter.go b/engine/reslimiter.go index e040a9f46..0028a7196 100644 --- a/engine/reslimiter.go +++ b/engine/reslimiter.go @@ -327,7 +327,7 @@ func (rls *ResourceLimiterService) V1InitiateResourceUsage(attrs utils.AttrRLsRe return utils.ErrResourceUnavailable } for _, rl := range matchingRLForEv { - cache2go.Set(utils.ResourceLimitsPrefix+rl.ID, rl) + cache2go.Set(utils.ResourceLimitsPrefix+rl.ID, rl, true, "") // no real reason for a transaction } *reply = utils.OK return nil diff --git a/engine/reslimiter_test.go b/engine/reslimiter_test.go index 01096d534..bdf70537d 100644 --- a/engine/reslimiter_test.go +++ b/engine/reslimiter_test.go @@ -78,7 +78,7 @@ func TestRLsIndexStringFilters(t *testing.T) { }, } for _, rl := range rls { - cache2go.Set(utils.ResourceLimitsPrefix+rl.ID, rl) + cache2go.Set(utils.ResourceLimitsPrefix+rl.ID, rl, true, "") } rLS = new(ResourceLimiterService) eIndexes := map[string]map[string]utils.StringMap{ @@ -122,7 +122,7 @@ func TestRLsIndexStringFilters(t *testing.T) { Limit: 1, Usage: make(map[string]*ResourceUsage), } - cache2go.Set(utils.ResourceLimitsPrefix+rl3.ID, rl3) + cache2go.Set(utils.ResourceLimitsPrefix+rl3.ID, rl3, true, "") rl6 := &ResourceLimit{ // Add it so we can test expiryTime ID: "RL6", Weight: 10, @@ -134,7 +134,7 @@ func TestRLsIndexStringFilters(t *testing.T) { Limit: 1, Usage: make(map[string]*ResourceUsage), } - cache2go.Set(utils.ResourceLimitsPrefix+rl6.ID, rl6) + cache2go.Set(utils.ResourceLimitsPrefix+rl6.ID, rl6, true, "") eIndexes = map[string]map[string]utils.StringMap{ "Account": map[string]utils.StringMap{ "1001": utils.StringMap{ diff --git a/engine/responder_test.go b/engine/responder_test.go index a90dd2dd5..15403a829 100644 --- a/engine/responder_test.go +++ b/engine/responder_test.go @@ -42,7 +42,7 @@ func TestResponderGetDerivedChargers(t *testing.T) { CategoryField: "test", AccountField: "test", SubjectField: "test", DestinationField: "test", SetupTimeField: "test", AnswerTimeField: "test", UsageField: "test"}}} rsponder = &Responder{} attrs := &utils.AttrDerivedChargers{Tenant: "cgrates.org", Category: "call", Direction: "*out", Account: "responder_test", Subject: "responder_test"} - if err := ratingStorage.SetDerivedChargers(utils.DerivedChargersKey(utils.OUT, utils.ANY, utils.ANY, utils.ANY, utils.ANY), cfgedDC); err != nil { + if err := ratingStorage.SetDerivedChargers(utils.DerivedChargersKey(utils.OUT, utils.ANY, utils.ANY, utils.ANY, utils.ANY), cfgedDC, utils.NonTransactional); err != nil { t.Error(err) } dcs := &utils.DerivedChargers{} @@ -67,10 +67,10 @@ func TestResponderGetDerivedMaxSessionTime(t *testing.T) { t.Error("Unexpected maxSessionTime received: ", maxSessionTime) } deTMobile := &Destination{Id: "DE_TMOBILE", Prefixes: []string{"+49151", "+49160", "+49170", "+49171", "+49175"}} - if err := ratingStorage.SetDestination(deTMobile); err != nil { + if err := ratingStorage.SetDestination(deTMobile, utils.NonTransactional); err != nil { t.Error(err) } - if err := ratingStorage.SetReverseDestination(deTMobile); err != nil { + if err := ratingStorage.SetReverseDestination(deTMobile, utils.NonTransactional); err != nil { t.Error(err) } b10 := &Balance{Value: 10, Weight: 10, DestinationIDs: utils.NewStringMap("DE_TMOBILE")} @@ -92,7 +92,7 @@ func TestResponderGetDerivedMaxSessionTime(t *testing.T) { &utils.DerivedCharger{RunID: "extra3", RequestTypeField: "^" + utils.META_PSEUDOPREPAID, DirectionField: "*default", TenantField: "*default", CategoryField: "*default", AccountField: "^rif", SubjectField: "^rif", DestinationField: "^+49151708707", SetupTimeField: "*default", AnswerTimeField: "*default", UsageField: "*default"}, }} - if err := ratingStorage.SetDerivedChargers(keyCharger1, charger1); err != nil { + if err := ratingStorage.SetDerivedChargers(keyCharger1, charger1, utils.NonTransactional); err != nil { t.Error("Error on setting DerivedChargers", err.Error()) } if rifStoredAcnt, err := accountingStorage.GetAccount(utils.ConcatenatedKey(testTenant, "rif")); err != nil { @@ -145,7 +145,7 @@ func TestResponderGetSessionRuns(t *testing.T) { SetupTimeField: utils.META_DEFAULT, PDDField: utils.META_DEFAULT, AnswerTimeField: utils.META_DEFAULT, UsageField: utils.META_DEFAULT, SupplierField: utils.META_DEFAULT, DisconnectCauseField: utils.META_DEFAULT} charger1 := &utils.DerivedChargers{Chargers: []*utils.DerivedCharger{extra1DC, extra2DC, extra3DC}} - if err := ratingStorage.SetDerivedChargers(keyCharger1, charger1); err != nil { + if err := ratingStorage.SetDerivedChargers(keyCharger1, charger1, utils.NonTransactional); err != nil { t.Error("Error on setting DerivedChargers", err.Error()) } sesRuns := make([]*SessionRun, 0) @@ -172,10 +172,10 @@ func TestResponderGetSessionRuns(t *testing.T) { func TestResponderGetLCR(t *testing.T) { rsponder.Stats = NewStats(ratingStorage, accountingStorage, 0) // Load stats instance dstDe := &Destination{Id: "GERMANY", Prefixes: []string{"+49"}} - if err := ratingStorage.SetDestination(dstDe); err != nil { + if err := ratingStorage.SetDestination(dstDe, utils.NonTransactional); err != nil { t.Error(err) } - if err := ratingStorage.SetReverseDestination(dstDe); err != nil { + if err := ratingStorage.SetReverseDestination(dstDe, utils.NonTransactional); err != nil { t.Error(err) } rp1 := &RatingPlan{ @@ -287,7 +287,7 @@ func TestResponderGetLCR(t *testing.T) { }, } for _, rpf := range []*RatingPlan{rp1, rp2, rp3} { - if err := ratingStorage.SetRatingPlan(rpf); err != nil { + if err := ratingStorage.SetRatingPlan(rpf, utils.NonTransactional); err != nil { t.Error(err) } } @@ -323,7 +323,7 @@ func TestResponderGetLCR(t *testing.T) { }}, } for _, rpfl := range []*RatingProfile{danRpfl, rifRpfl, ivoRpfl} { - if err := ratingStorage.SetRatingProfile(rpfl); err != nil { + if err := ratingStorage.SetRatingProfile(rpfl, utils.NonTransactional); err != nil { t.Error(err) } } @@ -373,7 +373,7 @@ func TestResponderGetLCR(t *testing.T) { }, } for _, lcr := range []*LCR{lcrStatic, lcrLowestCost, lcrQosThreshold, lcrQos, lcrLoad} { - if err := ratingStorage.SetLCR(lcr); err != nil { + if err := ratingStorage.SetLCR(lcr, utils.NonTransactional); err != nil { t.Error(err) } } diff --git a/engine/sharedgroup_test.go b/engine/sharedgroup_test.go index fd71f1531..6448efaf4 100644 --- a/engine/sharedgroup_test.go +++ b/engine/sharedgroup_test.go @@ -34,15 +34,15 @@ func TestSharedSetGet(t *testing.T) { }, MemberIds: utils.NewStringMap("1", "2", "3"), } - err := ratingStorage.SetSharedGroup(sg) + err := ratingStorage.SetSharedGroup(sg, utils.NonTransactional) if err != nil { t.Error("Error storing Shared groudp: ", err) } - received, err := ratingStorage.GetSharedGroup(id, true) + received, err := ratingStorage.GetSharedGroup(id, true, utils.NonTransactional) if err != nil || received == nil || !reflect.DeepEqual(sg, received) { t.Error("Error getting shared group: ", err, received) } - received, err = ratingStorage.GetSharedGroup(id, false) + received, err = ratingStorage.GetSharedGroup(id, false, utils.NonTransactional) if err != nil || received == nil || !reflect.DeepEqual(sg, received) { t.Error("Error getting cached shared group: ", err, received) } diff --git a/engine/storage_interface.go b/engine/storage_interface.go index 4fad025cf..7f28b5aa3 100644 --- a/engine/storage_interface.go +++ b/engine/storage_interface.go @@ -42,34 +42,34 @@ type RatingStorage interface { Storage HasData(string, string) (bool, error) PreloadRatingCache() error - GetRatingPlan(string, bool) (*RatingPlan, error) - SetRatingPlan(*RatingPlan) error - GetRatingProfile(string, bool) (*RatingProfile, error) - SetRatingProfile(*RatingProfile) error - RemoveRatingProfile(string) error - GetDestination(string, bool) (*Destination, error) - SetDestination(*Destination) error - RemoveDestination(string) error - SetReverseDestination(*Destination) error - GetReverseDestination(string, bool) ([]string, error) - UpdateReverseDestination(*Destination, *Destination) error - GetLCR(string, bool) (*LCR, error) - SetLCR(*LCR) error + GetRatingPlan(string, bool, string) (*RatingPlan, error) + SetRatingPlan(*RatingPlan, string) error + GetRatingProfile(string, bool, string) (*RatingProfile, error) + SetRatingProfile(*RatingProfile, string) error + RemoveRatingProfile(string, string) error + GetDestination(string, bool, string) (*Destination, error) + SetDestination(*Destination, string) error + RemoveDestination(string, string) error + SetReverseDestination(*Destination, string) error + GetReverseDestination(string, bool, string) ([]string, error) + UpdateReverseDestination(*Destination, *Destination, string) error + GetLCR(string, bool, string) (*LCR, error) + SetLCR(*LCR, string) error SetCdrStats(*CdrStats) error GetCdrStats(string) (*CdrStats, error) GetAllCdrStats() ([]*CdrStats, error) - GetDerivedChargers(string, bool) (*utils.DerivedChargers, error) - SetDerivedChargers(string, *utils.DerivedChargers) error - GetActions(string, bool) (Actions, error) - SetActions(string, Actions) error - RemoveActions(string) error - GetSharedGroup(string, bool) (*SharedGroup, error) - SetSharedGroup(*SharedGroup) error - GetActionTriggers(string, bool) (ActionTriggers, error) - SetActionTriggers(string, ActionTriggers) error - RemoveActionTriggers(string) error - GetActionPlan(string, bool) (*ActionPlan, error) - SetActionPlan(string, *ActionPlan, bool) error + GetDerivedChargers(string, bool, string) (*utils.DerivedChargers, error) + SetDerivedChargers(string, *utils.DerivedChargers, string) error + GetActions(string, bool, string) (Actions, error) + SetActions(string, Actions, string) error + RemoveActions(string, string) error + GetSharedGroup(string, bool, string) (*SharedGroup, error) + SetSharedGroup(*SharedGroup, string) error + GetActionTriggers(string, bool, string) (ActionTriggers, error) + SetActionTriggers(string, ActionTriggers, string) error + RemoveActionTriggers(string, string) error + GetActionPlan(string, bool, string) (*ActionPlan, error) + SetActionPlan(string, *ActionPlan, bool, string) error GetAllActionPlans() (map[string]*ActionPlan, error) PushTask(*Task) error PopTask() (*Task, error) @@ -90,17 +90,17 @@ type AccountingStorage interface { GetUser(string) (*UserProfile, error) GetUsers() ([]*UserProfile, error) RemoveUser(string) error - SetAlias(*Alias) error - GetAlias(string, bool) (*Alias, error) - RemoveAlias(string) error - SetReverseAlias(*Alias) error - GetReverseAlias(string, bool) ([]string, error) - UpdateReverseAlias(*Alias, *Alias) error - GetResourceLimit(string, bool) (*ResourceLimit, error) - SetResourceLimit(*ResourceLimit) error - RemoveResourceLimit(string) error - GetLoadHistory(int, bool) ([]*utils.LoadInstance, error) - AddLoadHistory(*utils.LoadInstance, int) error + SetAlias(*Alias, string) error + GetAlias(string, bool, string) (*Alias, error) + RemoveAlias(string, string) error + SetReverseAlias(*Alias, string) error + GetReverseAlias(string, bool, string) ([]string, error) + UpdateReverseAlias(*Alias, *Alias, string) error + GetResourceLimit(string, bool, string) (*ResourceLimit, error) + SetResourceLimit(*ResourceLimit, string) error + RemoveResourceLimit(string, string) error + GetLoadHistory(int, bool, string) ([]*utils.LoadInstance, error) + AddLoadHistory(*utils.LoadInstance, int, string) error GetStructVersion() (*StructVersion, error) SetStructVersion(*StructVersion) error } @@ -254,3 +254,11 @@ func (gm *GOBMarshaler) Marshal(v interface{}) (data []byte, err error) { func (gm *GOBMarshaler) Unmarshal(data []byte, v interface{}) error { return gob.NewDecoder(bytes.NewBuffer(data)).Decode(v) } + +// Decide the value of cacheCommit parameter based on transactionID +func cacheCommit(transactionID string) bool { + if transactionID == utils.NonTransactional { + return true + } + return false +} diff --git a/engine/storage_map.go b/engine/storage_map.go index 4dec98392..8fb88fd12 100644 --- a/engine/storage_map.go +++ b/engine/storage_map.go @@ -1,11 +1,11 @@ /* Real-time Charging System for Telecom & ISP environments -Copyright (C) 2012-2015 ITsysCOM GmbH +Copyright (C) ITsysCOM GmbH This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by -the Free Software Foundation, either vemsion 3 of the License, or -(at your option) any later vemsion. +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -23,9 +23,8 @@ import ( "compress/zlib" "errors" "io/ioutil" - "sync" - "strings" + "sync" "github.com/cgrates/cgrates/cache2go" "github.com/cgrates/cgrates/config" @@ -106,11 +105,11 @@ func (ms *MapStorage) RebuildReverseForPrefix(prefix string) error { return err } for _, key := range keys { - dest, err := ms.GetDestination(key[len(utils.DESTINATION_PREFIX):], false) + dest, err := ms.GetDestination(key[len(utils.DESTINATION_PREFIX):], false, utils.NonTransactional) if err != nil { return err } - if err := ms.SetReverseDestination(dest); err != nil { + if err := ms.SetReverseDestination(dest, utils.NonTransactional); err != nil { return err } } @@ -120,11 +119,11 @@ func (ms *MapStorage) RebuildReverseForPrefix(prefix string) error { return err } for _, key := range keys { - al, err := ms.GetAlias(key[len(utils.ALIASES_PREFIX):], false) + al, err := ms.GetAlias(key[len(utils.ALIASES_PREFIX):], false, utils.NonTransactional) if err != nil { return err } - if err := ms.SetReverseAlias(al); err != nil { + if err := ms.SetReverseAlias(al, utils.NonTransactional); err != nil { return err } } @@ -214,26 +213,27 @@ func (ms *MapStorage) PreloadAccountingCache() error { } func (ms *MapStorage) PreloadCacheForPrefix(prefix string) error { - cache2go.BeginTransaction() - cache2go.RemPrefixKey(prefix) + transID := cache2go.BeginTransaction() + cache2go.RemPrefixKey(prefix, false, transID) keyList, err := ms.GetKeysForPrefix(prefix) if err != nil { - cache2go.RollbackTransaction() + cache2go.RollbackTransaction(transID) return err } switch prefix { case utils.RATING_PLAN_PREFIX: for _, key := range keyList { - _, err := ms.GetRatingPlan(key[len(utils.RATING_PLAN_PREFIX):], true) + _, err := ms.GetRatingPlan(key[len(utils.RATING_PLAN_PREFIX):], true, transID) if err != nil { - cache2go.RollbackTransaction() + cache2go.RollbackTransaction(transID) return err } } default: + cache2go.RollbackTransaction(transID) return utils.ErrInvalidKey } - cache2go.CommitTransaction() + cache2go.CommitTransaction(transID) return nil } @@ -261,7 +261,7 @@ func (ms *MapStorage) HasData(categ, subject string) (bool, error) { return false, errors.New("Unsupported HasData category") } -func (ms *MapStorage) GetRatingPlan(key string, skipCache bool) (rp *RatingPlan, err error) { +func (ms *MapStorage) GetRatingPlan(key string, skipCache bool, transactionID string) (rp *RatingPlan, err error) { ms.mu.RLock() defer ms.mu.RUnlock() key = utils.RATING_PLAN_PREFIX + key @@ -273,6 +273,7 @@ func (ms *MapStorage) GetRatingPlan(key string, skipCache bool) (rp *RatingPlan, return nil, utils.ErrNotFound } } + cCommit := cacheCommit(transactionID) if values, ok := ms.dict[key]; ok { b := bytes.NewBuffer(values) r, err := zlib.NewReader(b) @@ -287,14 +288,14 @@ func (ms *MapStorage) GetRatingPlan(key string, skipCache bool) (rp *RatingPlan, rp = new(RatingPlan) err = ms.ms.Unmarshal(out, rp) } else { - cache2go.Set(key, nil) + cache2go.Set(key, nil, cCommit, transactionID) return nil, utils.ErrNotFound } - cache2go.Set(key, rp) + cache2go.Set(key, rp, cCommit, transactionID) return } -func (ms *MapStorage) SetRatingPlan(rp *RatingPlan) (err error) { +func (ms *MapStorage) SetRatingPlan(rp *RatingPlan, transactionID string) (err error) { ms.mu.Lock() defer ms.mu.Unlock() result, err := ms.ms.Marshal(rp) @@ -307,11 +308,11 @@ func (ms *MapStorage) SetRatingPlan(rp *RatingPlan) (err error) { if historyScribe != nil { go historyScribe.Call("HistoryV1.Record", rp.GetHistoryRecord(), &response) } - cache2go.RemKey(utils.RATING_PLAN_PREFIX + rp.Id) + cache2go.RemKey(utils.RATING_PLAN_PREFIX+rp.Id, cacheCommit(transactionID), transactionID) return } -func (ms *MapStorage) GetRatingProfile(key string, skipCache bool) (rpf *RatingProfile, err error) { +func (ms *MapStorage) GetRatingProfile(key string, skipCache bool, transactionID string) (rpf *RatingProfile, err error) { ms.mu.RLock() defer ms.mu.RUnlock() key = utils.RATING_PROFILE_PREFIX + key @@ -323,20 +324,19 @@ func (ms *MapStorage) GetRatingProfile(key string, skipCache bool) (rpf *RatingP return nil, utils.ErrNotFound } } - + cCommit := cacheCommit(transactionID) if values, ok := ms.dict[key]; ok { rpf = new(RatingProfile) - err = ms.ms.Unmarshal(values, rpf) } else { - cache2go.Set(key, nil) + cache2go.Set(key, nil, cCommit, transactionID) return nil, utils.ErrNotFound } - cache2go.Set(key, rpf) + cache2go.Set(key, rpf, cCommit, transactionID) return } -func (ms *MapStorage) SetRatingProfile(rpf *RatingProfile) (err error) { +func (ms *MapStorage) SetRatingProfile(rpf *RatingProfile, transactionID string) (err error) { ms.mu.Lock() defer ms.mu.Unlock() result, err := ms.ms.Marshal(rpf) @@ -345,17 +345,17 @@ func (ms *MapStorage) SetRatingProfile(rpf *RatingProfile) (err error) { if historyScribe != nil { go historyScribe.Call("HistoryV1.Record", rpf.GetHistoryRecord(false), &response) } - cache2go.RemKey(utils.RATING_PROFILE_PREFIX + rpf.Id) + cache2go.RemKey(utils.RATING_PROFILE_PREFIX+rpf.Id, cacheCommit(transactionID), transactionID) return } -func (ms *MapStorage) RemoveRatingProfile(key string) (err error) { +func (ms *MapStorage) RemoveRatingProfile(key string, transactionID string) (err error) { ms.mu.Lock() defer ms.mu.Unlock() for k := range ms.dict { if strings.HasPrefix(k, key) { delete(ms.dict, key) - cache2go.RemKey(k) + cache2go.RemKey(k, cacheCommit(transactionID), transactionID) response := 0 rpf := &RatingProfile{Id: key} if historyScribe != nil { @@ -366,7 +366,7 @@ func (ms *MapStorage) RemoveRatingProfile(key string) (err error) { return } -func (ms *MapStorage) GetLCR(key string, skipCache bool) (lcr *LCR, err error) { +func (ms *MapStorage) GetLCR(key string, skipCache bool, transactionID string) (lcr *LCR, err error) { ms.mu.RLock() defer ms.mu.RUnlock() key = utils.LCR_PREFIX + key @@ -378,28 +378,30 @@ func (ms *MapStorage) GetLCR(key string, skipCache bool) (lcr *LCR, err error) { return nil, utils.ErrNotFound } } + cCommit := cacheCommit(transactionID) if values, ok := ms.dict[key]; ok { err = ms.ms.Unmarshal(values, &lcr) } else { - cache2go.Set(key, nil) + cache2go.Set(key, nil, cCommit, transactionID) return nil, utils.ErrNotFound } - cache2go.Set(key, lcr) + cache2go.Set(key, lcr, cCommit, transactionID) return } -func (ms *MapStorage) SetLCR(lcr *LCR) (err error) { +func (ms *MapStorage) SetLCR(lcr *LCR, transactionID string) (err error) { ms.mu.Lock() defer ms.mu.Unlock() result, err := ms.ms.Marshal(lcr) ms.dict[utils.LCR_PREFIX+lcr.GetId()] = result - cache2go.RemKey(utils.LCR_PREFIX + lcr.GetId()) + cache2go.RemKey(utils.LCR_PREFIX+lcr.GetId(), cacheCommit(transactionID), transactionID) return } -func (ms *MapStorage) GetDestination(key string, skipCache bool) (dest *Destination, err error) { +func (ms *MapStorage) GetDestination(key string, skipCache bool, transactionID string) (dest *Destination, err error) { ms.mu.RLock() defer ms.mu.RUnlock() + cCommit := cacheCommit(transactionID) key = utils.DESTINATION_PREFIX + key if !skipCache { if x, ok := cache2go.Get(key); ok { @@ -423,16 +425,16 @@ func (ms *MapStorage) GetDestination(key string, skipCache bool) (dest *Destinat dest = new(Destination) err = ms.ms.Unmarshal(out, dest) if err != nil { - cache2go.Set(key, dest) + cache2go.Set(key, dest, cCommit, transactionID) } } else { - cache2go.Set(key, nil) + cache2go.Set(key, nil, cCommit, transactionID) return nil, utils.ErrNotFound } return } -func (ms *MapStorage) SetDestination(dest *Destination) (err error) { +func (ms *MapStorage) SetDestination(dest *Destination, transactionID string) (err error) { ms.mu.Lock() defer ms.mu.Unlock() result, err := ms.ms.Marshal(dest) @@ -446,11 +448,11 @@ func (ms *MapStorage) SetDestination(dest *Destination) (err error) { if historyScribe != nil { go historyScribe.Call("HistoryV1.Record", dest.GetHistoryRecord(false), &response) } - cache2go.RemKey(key) + cache2go.RemKey(key, cacheCommit(transactionID), transactionID) return } -func (ms *MapStorage) GetReverseDestination(prefix string, skipCache bool) (ids []string, err error) { +func (ms *MapStorage) GetReverseDestination(prefix string, skipCache bool, transactionID string) (ids []string, err error) { ms.mu.Lock() defer ms.mu.Unlock() prefix = utils.REVERSE_DESTINATION_PREFIX + prefix @@ -462,53 +464,49 @@ func (ms *MapStorage) GetReverseDestination(prefix string, skipCache bool) (ids return nil, utils.ErrNotFound } } - if idMap, ok := ms.dict.smembers(prefix, ms.ms); ok { ids = idMap.Slice() } else { - cache2go.Set(prefix, nil) + cache2go.Set(prefix, nil, cacheCommit(transactionID), transactionID) return nil, utils.ErrNotFound } - - cache2go.Set(prefix, ids) + cache2go.Set(prefix, ids, cacheCommit(transactionID), transactionID) return } -func (ms *MapStorage) SetReverseDestination(dest *Destination) (err error) { +func (ms *MapStorage) SetReverseDestination(dest *Destination, transactionID string) (err error) { for _, p := range dest.Prefixes { key := utils.REVERSE_DESTINATION_PREFIX + p ms.mu.Lock() ms.dict.sadd(key, dest.Id, ms.ms) ms.mu.Unlock() - cache2go.RemKey(key) + cache2go.RemKey(key, cacheCommit(transactionID), transactionID) } return } -func (ms *MapStorage) RemoveDestination(destID string) (err error) { +func (ms *MapStorage) RemoveDestination(destID string, transactionID string) (err error) { key := utils.DESTINATION_PREFIX + destID // get destination for prefix list - d, err := ms.GetDestination(destID, false) + d, err := ms.GetDestination(destID, false, transactionID) if err != nil { return } ms.mu.Lock() delete(ms.dict, key) ms.mu.Unlock() - cache2go.RemKey(key) - + cache2go.RemKey(key, cacheCommit(transactionID), transactionID) for _, prefix := range d.Prefixes { ms.mu.Lock() ms.dict.srem(utils.REVERSE_DESTINATION_PREFIX+prefix, destID, ms.ms) ms.mu.Unlock() - - ms.GetReverseDestination(prefix, true) // it will recache the destination + ms.GetReverseDestination(prefix, true, transactionID) // it will recache the destination } return } -func (ms *MapStorage) UpdateReverseDestination(oldDest, newDest *Destination) error { +func (ms *MapStorage) UpdateReverseDestination(oldDest, newDest *Destination, transactionID string) error { //log.Printf("Old: %+v, New: %+v", oldDest, newDest) var obsoletePrefixes []string var addedPrefixes []string @@ -541,12 +539,13 @@ func (ms *MapStorage) UpdateReverseDestination(oldDest, newDest *Destination) er //log.Print("Obsolete prefixes: ", obsoletePrefixes) //log.Print("Added prefixes: ", addedPrefixes) // remove id for all obsolete prefixes + cCommit := cacheCommit(transactionID) var err error for _, obsoletePrefix := range obsoletePrefixes { ms.mu.Lock() ms.dict.srem(utils.REVERSE_DESTINATION_PREFIX+obsoletePrefix, oldDest.Id, ms.ms) ms.mu.Unlock() - cache2go.RemKey(utils.REVERSE_DESTINATION_PREFIX + obsoletePrefix) + cache2go.RemKey(utils.REVERSE_DESTINATION_PREFIX+obsoletePrefix, cCommit, transactionID) } // add the id to all new prefixes @@ -554,14 +553,15 @@ func (ms *MapStorage) UpdateReverseDestination(oldDest, newDest *Destination) er ms.mu.Lock() ms.dict.sadd(utils.REVERSE_DESTINATION_PREFIX+addedPrefix, newDest.Id, ms.ms) ms.mu.Unlock() - cache2go.RemKey(utils.REVERSE_DESTINATION_PREFIX + addedPrefix) + cache2go.RemKey(utils.REVERSE_DESTINATION_PREFIX+addedPrefix, cCommit, transactionID) } return err } -func (ms *MapStorage) GetActions(key string, skipCache bool) (as Actions, err error) { +func (ms *MapStorage) GetActions(key string, skipCache bool, transactionID string) (as Actions, err error) { ms.mu.RLock() defer ms.mu.RUnlock() + cCommit := cacheCommit(transactionID) key = utils.ACTION_PREFIX + key if !skipCache { if x, ok := cache2go.Get(key); ok { @@ -574,31 +574,32 @@ func (ms *MapStorage) GetActions(key string, skipCache bool) (as Actions, err er if values, ok := ms.dict[key]; ok { err = ms.ms.Unmarshal(values, &as) } else { - cache2go.Set(key, nil) + cache2go.Set(key, nil, cCommit, transactionID) return nil, utils.ErrNotFound } - cache2go.Set(key, as) + cache2go.Set(key, as, cCommit, transactionID) return } -func (ms *MapStorage) SetActions(key string, as Actions) (err error) { +func (ms *MapStorage) SetActions(key string, as Actions, transactionID string) (err error) { ms.mu.Lock() defer ms.mu.Unlock() + cCommit := cacheCommit(transactionID) result, err := ms.ms.Marshal(&as) ms.dict[utils.ACTION_PREFIX+key] = result - cache2go.RemKey(utils.ACTION_PREFIX + key) + cache2go.RemKey(utils.ACTION_PREFIX+key, cCommit, transactionID) return } -func (ms *MapStorage) RemoveActions(key string) (err error) { +func (ms *MapStorage) RemoveActions(key string, transactionID string) (err error) { ms.mu.Lock() defer ms.mu.Unlock() delete(ms.dict, utils.ACTION_PREFIX+key) - cache2go.RemKey(utils.ACTION_PREFIX + key) + cache2go.RemKey(utils.ACTION_PREFIX+key, cacheCommit(transactionID), transactionID) return } -func (ms *MapStorage) GetSharedGroup(key string, skipCache bool) (sg *SharedGroup, err error) { +func (ms *MapStorage) GetSharedGroup(key string, skipCache bool, transactionID string) (sg *SharedGroup, err error) { ms.mu.RLock() defer ms.mu.RUnlock() key = utils.SHARED_GROUP_PREFIX + key @@ -610,24 +611,25 @@ func (ms *MapStorage) GetSharedGroup(key string, skipCache bool) (sg *SharedGrou return nil, utils.ErrNotFound } } + cCommit := cacheCommit(transactionID) if values, ok := ms.dict[key]; ok { err = ms.ms.Unmarshal(values, &sg) if err == nil { - cache2go.Set(key, sg) + cache2go.Set(key, sg, cCommit, transactionID) } } else { - cache2go.Set(key, nil) + cache2go.Set(key, nil, cCommit, transactionID) return nil, utils.ErrNotFound } return } -func (ms *MapStorage) SetSharedGroup(sg *SharedGroup) (err error) { +func (ms *MapStorage) SetSharedGroup(sg *SharedGroup, transactionID string) (err error) { ms.mu.Lock() defer ms.mu.Unlock() result, err := ms.ms.Marshal(sg) ms.dict[utils.SHARED_GROUP_PREFIX+sg.Id] = result - cache2go.RemKey(utils.SHARED_GROUP_PREFIX + sg.Id) + cache2go.RemKey(utils.SHARED_GROUP_PREFIX+sg.Id, cacheCommit(transactionID), transactionID) return } @@ -762,7 +764,7 @@ func (ms *MapStorage) RemoveUser(key string) error { return nil } -func (ms *MapStorage) GetAlias(key string, skipCache bool) (al *Alias, err error) { +func (ms *MapStorage) GetAlias(key string, skipCache bool, transactionID string) (al *Alias, err error) { ms.mu.RLock() defer ms.mu.RUnlock() origKey := key @@ -777,21 +779,22 @@ func (ms *MapStorage) GetAlias(key string, skipCache bool) (al *Alias, err error return nil, utils.ErrNotFound } } + cCommit := cacheCommit(transactionID) if values, ok := ms.dict[key]; ok { al = &Alias{Values: make(AliasValues, 0)} al.SetId(key[len(utils.ALIASES_PREFIX):]) err = ms.ms.Unmarshal(values, &al.Values) if err == nil { - cache2go.Set(key, al.Values) + cache2go.Set(key, al.Values, cCommit, transactionID) } } else { - cache2go.Set(key, nil) + cache2go.Set(key, nil, cCommit, transactionID) return nil, utils.ErrNotFound } return al, nil } -func (ms *MapStorage) SetAlias(al *Alias) error { +func (ms *MapStorage) SetAlias(al *Alias, transactionID string) error { ms.mu.Lock() defer ms.mu.Unlock() result, err := ms.ms.Marshal(al.Values) @@ -800,11 +803,11 @@ func (ms *MapStorage) SetAlias(al *Alias) error { } key := utils.ALIASES_PREFIX + al.GetId() ms.dict[key] = result - cache2go.RemKey(key) + cache2go.RemKey(key, cacheCommit(transactionID), transactionID) return nil } -func (ms *MapStorage) GetReverseAlias(reverseID string, skipCache bool) (ids []string, err error) { +func (ms *MapStorage) GetReverseAlias(reverseID string, skipCache bool, transactionID string) (ids []string, err error) { ms.mu.Lock() defer ms.mu.Unlock() key := utils.REVERSE_ALIASES_PREFIX + reverseID @@ -817,18 +820,19 @@ func (ms *MapStorage) GetReverseAlias(reverseID string, skipCache bool) (ids []s } } var values []string + cCommit := cacheCommit(transactionID) if idMap, ok := ms.dict.smembers(key, ms.ms); len(idMap) > 0 && ok { values = idMap.Slice() } else { - cache2go.Set(key, nil) + cache2go.Set(key, nil, cCommit, transactionID) return nil, utils.ErrNotFound } - cache2go.Set(key, values) + cache2go.Set(key, values, cCommit, transactionID) return - } -func (ms *MapStorage) SetReverseAlias(al *Alias) (err error) { +func (ms *MapStorage) SetReverseAlias(al *Alias, transactionID string) (err error) { + cCommit := cacheCommit(transactionID) for _, value := range al.Values { for target, pairs := range value.Pairs { for _, alias := range pairs { @@ -838,16 +842,16 @@ func (ms *MapStorage) SetReverseAlias(al *Alias) (err error) { ms.dict.sadd(rKey, id, ms.ms) ms.mu.Unlock() - cache2go.RemKey(rKey) + cache2go.RemKey(rKey, cCommit, transactionID) } } } return } -func (ms *MapStorage) RemoveAlias(key string) error { +func (ms *MapStorage) RemoveAlias(key string, transactionID string) error { // get alias for values list - al, err := ms.GetAlias(key, false) + al, err := ms.GetAlias(key, false, transactionID) if err != nil { return err } @@ -861,15 +865,15 @@ func (ms *MapStorage) RemoveAlias(key string) error { ms.ms.Unmarshal(values, &aliasValues) } delete(ms.dict, key) - cache2go.RemKey(key) + cCommit := cacheCommit(transactionID) + cache2go.RemKey(key, cCommit, transactionID) for _, value := range al.Values { tmpKey := utils.ConcatenatedKey(al.GetId(), value.DestinationId) for target, pairs := range value.Pairs { for _, alias := range pairs { rKey := utils.REVERSE_ALIASES_PREFIX + alias + target + al.Context ms.dict.srem(rKey, tmpKey, ms.ms) - - cache2go.RemKey(rKey) + cache2go.RemKey(rKey, cCommit, transactionID) /*_, err = ms.GetReverseAlias(rKey, true) // recache if err != nil { return err @@ -880,25 +884,26 @@ func (ms *MapStorage) RemoveAlias(key string) error { return nil } -func (ms *MapStorage) UpdateReverseAlias(oldAl, newAl *Alias) error { +func (ms *MapStorage) UpdateReverseAlias(oldAl, newAl *Alias, transactionID string) error { return nil } -func (ms *MapStorage) GetLoadHistory(limitItems int, skipCache bool) ([]*utils.LoadInstance, error) { +func (ms *MapStorage) GetLoadHistory(limitItems int, skipCache bool, transactionID string) ([]*utils.LoadInstance, error) { ms.mu.RLock() defer ms.mu.RUnlock() return nil, nil } -func (ms *MapStorage) AddLoadHistory(*utils.LoadInstance, int) error { +func (ms *MapStorage) AddLoadHistory(*utils.LoadInstance, int, string) error { ms.mu.Lock() defer ms.mu.Unlock() return nil } -func (ms *MapStorage) GetActionTriggers(key string, skipCache bool) (atrs ActionTriggers, err error) { +func (ms *MapStorage) GetActionTriggers(key string, skipCache bool, transactionID string) (atrs ActionTriggers, err error) { ms.mu.RLock() defer ms.mu.RUnlock() + cCommit := cacheCommit(transactionID) key = utils.ACTION_TRIGGER_PREFIX + key if !skipCache { if x, ok := cache2go.Get(key); ok { @@ -911,14 +916,14 @@ func (ms *MapStorage) GetActionTriggers(key string, skipCache bool) (atrs Action if values, ok := ms.dict[key]; ok { err = ms.ms.Unmarshal(values, &atrs) } else { - cache2go.Set(key, nil) + cache2go.Set(key, nil, cCommit, transactionID) return nil, utils.ErrNotFound } - cache2go.Set(key, atrs) + cache2go.Set(key, atrs, cCommit, transactionID) return } -func (ms *MapStorage) SetActionTriggers(key string, atrs ActionTriggers) (err error) { +func (ms *MapStorage) SetActionTriggers(key string, atrs ActionTriggers, transactionID string) (err error) { ms.mu.Lock() defer ms.mu.Unlock() if len(atrs) == 0 { @@ -928,19 +933,19 @@ func (ms *MapStorage) SetActionTriggers(key string, atrs ActionTriggers) (err er } result, err := ms.ms.Marshal(&atrs) ms.dict[utils.ACTION_TRIGGER_PREFIX+key] = result - cache2go.RemKey(utils.ACTION_TRIGGER_PREFIX + key) + cache2go.RemKey(utils.ACTION_TRIGGER_PREFIX+key, cacheCommit(transactionID), transactionID) return } -func (ms *MapStorage) RemoveActionTriggers(key string) (err error) { +func (ms *MapStorage) RemoveActionTriggers(key string, transactionID string) (err error) { ms.mu.Lock() defer ms.mu.Unlock() delete(ms.dict, utils.ACTION_TRIGGER_PREFIX+key) - cache2go.RemKey(key) + cache2go.RemKey(key, cacheCommit(transactionID), transactionID) return } -func (ms *MapStorage) GetActionPlan(key string, skipCache bool) (ats *ActionPlan, err error) { +func (ms *MapStorage) GetActionPlan(key string, skipCache bool, transactionID string) (ats *ActionPlan, err error) { ms.mu.RLock() defer ms.mu.RUnlock() key = utils.ACTION_PLAN_PREFIX + key @@ -955,25 +960,26 @@ func (ms *MapStorage) GetActionPlan(key string, skipCache bool) (ats *ActionPlan if values, ok := ms.dict[key]; ok { err = ms.ms.Unmarshal(values, &ats) } else { - cache2go.Set(key, nil) + cache2go.Set(key, nil, cacheCommit(transactionID), transactionID) return nil, utils.ErrNotFound } - cache2go.Set(key, ats) + cache2go.Set(key, ats, cacheCommit(transactionID), transactionID) return } -func (ms *MapStorage) SetActionPlan(key string, ats *ActionPlan, overwrite bool) (err error) { +func (ms *MapStorage) SetActionPlan(key string, ats *ActionPlan, overwrite bool, transactionID string) (err error) { + cCommit := cacheCommit(transactionID) if len(ats.ActionTimings) == 0 { ms.mu.Lock() defer ms.mu.Unlock() // delete the key delete(ms.dict, utils.ACTION_PLAN_PREFIX+key) - cache2go.RemKey(utils.ACTION_PLAN_PREFIX + key) + cache2go.RemKey(utils.ACTION_PLAN_PREFIX+key, cCommit, transactionID) return } if !overwrite { // get existing action plan to merge the account ids - if existingAts, _ := ms.GetActionPlan(key, true); existingAts != nil { + if existingAts, _ := ms.GetActionPlan(key, true, transactionID); existingAts != nil { if ats.AccountIDs == nil && len(existingAts.AccountIDs) > 0 { ats.AccountIDs = make(utils.StringMap) } @@ -986,7 +992,7 @@ func (ms *MapStorage) SetActionPlan(key string, ats *ActionPlan, overwrite bool) defer ms.mu.Unlock() result, err := ms.ms.Marshal(&ats) ms.dict[utils.ACTION_PLAN_PREFIX+key] = result - cache2go.RemKey(utils.ACTION_PLAN_PREFIX + key) + cache2go.RemKey(utils.ACTION_PLAN_PREFIX+key, cCommit, transactionID) return } @@ -998,7 +1004,7 @@ func (ms *MapStorage) GetAllActionPlans() (ats map[string]*ActionPlan, err error ats = make(map[string]*ActionPlan, len(keys)) for _, key := range keys { - ap, err := ms.GetActionPlan(key[len(utils.ACTION_PLAN_PREFIX):], false) + ap, err := ms.GetActionPlan(key[len(utils.ACTION_PLAN_PREFIX):], false, utils.NonTransactional) if err != nil { return nil, err } @@ -1033,9 +1039,10 @@ func (ms *MapStorage) PopTask() (t *Task, err error) { return } -func (ms *MapStorage) GetDerivedChargers(key string, skipCache bool) (dcs *utils.DerivedChargers, err error) { +func (ms *MapStorage) GetDerivedChargers(key string, skipCache bool, transactionID string) (dcs *utils.DerivedChargers, err error) { ms.mu.RLock() defer ms.mu.RUnlock() + cCommit := cacheCommit(transactionID) key = utils.DERIVEDCHARGERS_PREFIX + key if !skipCache { if x, ok := cache2go.Get(key); ok { @@ -1048,25 +1055,26 @@ func (ms *MapStorage) GetDerivedChargers(key string, skipCache bool) (dcs *utils if values, ok := ms.dict[key]; ok { err = ms.ms.Unmarshal(values, &dcs) } else { - cache2go.Set(key, nil) + cache2go.Set(key, nil, cCommit, transactionID) return nil, utils.ErrNotFound } - cache2go.Set(key, dcs) + cache2go.Set(key, dcs, cCommit, transactionID) return } -func (ms *MapStorage) SetDerivedChargers(key string, dcs *utils.DerivedChargers) error { +func (ms *MapStorage) SetDerivedChargers(key string, dcs *utils.DerivedChargers, transactionID string) error { ms.mu.Lock() defer ms.mu.Unlock() + cCommit := cacheCommit(transactionID) key = utils.DERIVEDCHARGERS_PREFIX + key if dcs == nil || len(dcs.Chargers) == 0 { delete(ms.dict, key) - cache2go.RemKey(key) + cache2go.RemKey(key, cCommit, transactionID) return nil } result, err := ms.ms.Marshal(dcs) ms.dict[key] = result - cache2go.RemKey(key) + cache2go.RemKey(key, cCommit, transactionID) return err } @@ -1146,13 +1154,13 @@ func (ms *MapStorage) GetStructVersion() (rsv *StructVersion, err error) { return } -func (ms *MapStorage) GetResourceLimit(id string, skipCache bool) (*ResourceLimit, error) { +func (ms *MapStorage) GetResourceLimit(id string, skipCache bool, transactionID string) (*ResourceLimit, error) { return nil, nil } -func (ms *MapStorage) SetResourceLimit(rl *ResourceLimit) error { +func (ms *MapStorage) SetResourceLimit(rl *ResourceLimit, transactionID string) error { return nil } -func (ms *MapStorage) RemoveResourceLimit(id string) error { +func (ms *MapStorage) RemoveResourceLimit(id string, transactionID string) error { return nil } diff --git a/engine/storage_mongo_datadb.go b/engine/storage_mongo_datadb.go index 7d15abd49..051567845 100644 --- a/engine/storage_mongo_datadb.go +++ b/engine/storage_mongo_datadb.go @@ -358,11 +358,11 @@ func (ms *MongoStorage) RebuildReverseForPrefix(prefix string) error { return err } for _, key := range keys { - dest, err := ms.GetDestination(key[len(utils.DESTINATION_PREFIX):], false) + dest, err := ms.GetDestination(key[len(utils.DESTINATION_PREFIX):], false, utils.NonTransactional) if err != nil { return err } - if err := ms.SetReverseDestination(dest); err != nil { + if err := ms.SetReverseDestination(dest, utils.NonTransactional); err != nil { return err } } @@ -372,11 +372,11 @@ func (ms *MongoStorage) RebuildReverseForPrefix(prefix string) error { return err } for _, key := range keys { - al, err := ms.GetAlias(key[len(utils.ALIASES_PREFIX):], false) + al, err := ms.GetAlias(key[len(utils.ALIASES_PREFIX):], false, utils.NonTransactional) if err != nil { return err } - if err := ms.SetReverseAlias(al); err != nil { + if err := ms.SetReverseAlias(al, utils.NonTransactional); err != nil { return err } } @@ -466,26 +466,26 @@ func (ms *MongoStorage) PreloadAccountingCache() error { } func (ms *MongoStorage) PreloadCacheForPrefix(prefix string) error { - cache2go.BeginTransaction() - cache2go.RemPrefixKey(prefix) + transID := cache2go.BeginTransaction() + cache2go.RemPrefixKey(prefix, false, transID) keyList, err := ms.GetKeysForPrefix(prefix) if err != nil { - cache2go.RollbackTransaction() + cache2go.RollbackTransaction(transID) return err } switch prefix { case utils.RATING_PLAN_PREFIX: for _, key := range keyList { - _, err := ms.GetRatingPlan(key[len(utils.RATING_PLAN_PREFIX):], true) + _, err := ms.GetRatingPlan(key[len(utils.RATING_PLAN_PREFIX):], true, transID) if err != nil { - cache2go.RollbackTransaction() + cache2go.RollbackTransaction(transID) return err } } default: return utils.ErrInvalidKey } - cache2go.CommitTransaction() + cache2go.CommitTransaction(transID) return nil } @@ -584,7 +584,7 @@ func (ms *MongoStorage) HasData(category, subject string) (bool, error) { return false, errors.New("unsupported category in HasData") } -func (ms *MongoStorage) GetRatingPlan(key string, skipCache bool) (rp *RatingPlan, err error) { +func (ms *MongoStorage) GetRatingPlan(key string, skipCache bool, transactionID string) (rp *RatingPlan, err error) { if !skipCache { if x, ok := cache2go.Get(utils.RATING_PLAN_PREFIX + key); ok { if x != nil { @@ -617,11 +617,11 @@ func (ms *MongoStorage) GetRatingPlan(key string, skipCache bool) (rp *RatingPla return nil, err } } - cache2go.Set(utils.RATING_PLAN_PREFIX+key, rp) + cache2go.Set(utils.RATING_PLAN_PREFIX+key, rp, cacheCommit(transactionID), transactionID) return } -func (ms *MongoStorage) SetRatingPlan(rp *RatingPlan) error { +func (ms *MongoStorage) SetRatingPlan(rp *RatingPlan, transactionID string) error { result, err := ms.ms.Marshal(rp) if err != nil { return err @@ -640,11 +640,11 @@ func (ms *MongoStorage) SetRatingPlan(rp *RatingPlan) error { var response int historyScribe.Call("HistoryV1.Record", rp.GetHistoryRecord(), &response) } - cache2go.Set(utils.RATING_PLAN_PREFIX+rp.Id, rp) + cache2go.Set(utils.RATING_PLAN_PREFIX+rp.Id, rp, cacheCommit(transactionID), transactionID) return err } -func (ms *MongoStorage) GetRatingProfile(key string, skipCache bool) (rp *RatingProfile, err error) { +func (ms *MongoStorage) GetRatingProfile(key string, skipCache bool, transactionID string) (rp *RatingProfile, err error) { if !skipCache { if x, ok := cache2go.Get(utils.RATING_PROFILE_PREFIX + key); ok { if x != nil { @@ -658,14 +658,14 @@ func (ms *MongoStorage) GetRatingProfile(key string, skipCache bool) (rp *Rating defer session.Close() err = col.Find(bson.M{"id": key}).One(rp) if err == nil { - cache2go.Set(utils.RATING_PROFILE_PREFIX+key, rp) + cache2go.Set(utils.RATING_PROFILE_PREFIX+key, rp, cacheCommit(transactionID), transactionID) } else { - cache2go.Set(utils.RATING_PROFILE_PREFIX+key, nil) + cache2go.Set(utils.RATING_PROFILE_PREFIX+key, nil, cacheCommit(transactionID), transactionID) } return } -func (ms *MongoStorage) SetRatingProfile(rp *RatingProfile) error { +func (ms *MongoStorage) SetRatingProfile(rp *RatingProfile, transactionID string) error { session, col := ms.conn(colRpf) defer session.Close() _, err := col.Upsert(bson.M{"id": rp.Id}, rp) @@ -673,11 +673,11 @@ func (ms *MongoStorage) SetRatingProfile(rp *RatingProfile) error { var response int historyScribe.Call("HistoryV1.Record", rp.GetHistoryRecord(false), &response) } - cache2go.RemKey(utils.RATING_PROFILE_PREFIX + rp.Id) + cache2go.RemKey(utils.RATING_PROFILE_PREFIX+rp.Id, cacheCommit(transactionID), transactionID) return err } -func (ms *MongoStorage) RemoveRatingProfile(key string) error { +func (ms *MongoStorage) RemoveRatingProfile(key, transactionID string) error { session, col := ms.conn(colRpf) defer session.Close() iter := col.Find(bson.M{"id": bson.RegEx{Pattern: key + ".*", Options: ""}}).Select(bson.M{"id": 1}).Iter() @@ -686,7 +686,7 @@ func (ms *MongoStorage) RemoveRatingProfile(key string) error { if err := col.Remove(bson.M{"id": result.Id}); err != nil { return err } - cache2go.RemKey(utils.RATING_PROFILE_PREFIX + key) + cache2go.RemKey(utils.RATING_PROFILE_PREFIX+key, cacheCommit(transactionID), transactionID) rpf := &RatingProfile{Id: result.Id} if historyScribe != nil { var response int @@ -696,7 +696,7 @@ func (ms *MongoStorage) RemoveRatingProfile(key string) error { return iter.Close() } -func (ms *MongoStorage) GetLCR(key string, skipCache bool) (lcr *LCR, err error) { +func (ms *MongoStorage) GetLCR(key string, skipCache bool, transactionID string) (lcr *LCR, err error) { if !skipCache { if x, ok := cache2go.Get(utils.LCR_PREFIX + key); ok { if x != nil { @@ -711,28 +711,29 @@ func (ms *MongoStorage) GetLCR(key string, skipCache bool) (lcr *LCR, err error) } session, col := ms.conn(colLcr) defer session.Close() + cCommit := cacheCommit(transactionID) if err = col.Find(bson.M{"key": key}).One(&result); err == nil { lcr = result.Value } else { - cache2go.Set(utils.LCR_PREFIX+key, nil) + cache2go.Set(utils.LCR_PREFIX+key, nil, cCommit, transactionID) return nil, utils.ErrNotFound } - cache2go.Set(utils.LCR_PREFIX+key, lcr) + cache2go.Set(utils.LCR_PREFIX+key, lcr, cCommit, transactionID) return } -func (ms *MongoStorage) SetLCR(lcr *LCR) error { +func (ms *MongoStorage) SetLCR(lcr *LCR, transactionID string) error { session, col := ms.conn(colLcr) defer session.Close() _, err := col.Upsert(bson.M{"key": lcr.GetId()}, &struct { Key string Value *LCR }{lcr.GetId(), lcr}) - cache2go.RemKey(utils.LCR_PREFIX + lcr.GetId()) + cache2go.RemKey(utils.LCR_PREFIX+lcr.GetId(), cacheCommit(transactionID), transactionID) return err } -func (ms *MongoStorage) GetDestination(key string, skipCache bool) (result *Destination, err error) { +func (ms *MongoStorage) GetDestination(key string, skipCache bool, transactionID string) (result *Destination, err error) { if !skipCache { if x, ok := cache2go.Get(utils.DESTINATION_PREFIX + key); ok { if x != nil { @@ -768,10 +769,10 @@ func (ms *MongoStorage) GetDestination(key string, skipCache bool) (result *Dest if err != nil { result = nil } - cache2go.Set(utils.DESTINATION_PREFIX+key, result) + cache2go.Set(utils.DESTINATION_PREFIX+key, result, cacheCommit(transactionID), transactionID) return } -func (ms *MongoStorage) SetDestination(dest *Destination) (err error) { +func (ms *MongoStorage) SetDestination(dest *Destination, transactionID string) (err error) { result, err := ms.ms.Marshal(dest) if err != nil { return err @@ -786,7 +787,7 @@ func (ms *MongoStorage) SetDestination(dest *Destination) (err error) { Key string Value []byte }{Key: dest.Id, Value: b.Bytes()}) - cache2go.RemKey(utils.DESTINATION_PREFIX + dest.Id) + cache2go.RemKey(utils.DESTINATION_PREFIX+dest.Id, cacheCommit(transactionID), transactionID) if err == nil && historyScribe != nil { var response int historyScribe.Call("HistoryV1.Record", dest.GetHistoryRecord(false), &response) @@ -794,7 +795,7 @@ func (ms *MongoStorage) SetDestination(dest *Destination) (err error) { return } -func (ms *MongoStorage) GetReverseDestination(prefix string, skipCache bool) (ids []string, err error) { +func (ms *MongoStorage) GetReverseDestination(prefix string, skipCache bool, transactionID string) (ids []string, err error) { if !skipCache { if x, ok := cache2go.Get(utils.REVERSE_DESTINATION_PREFIX + prefix); ok { if x != nil { @@ -813,28 +814,29 @@ func (ms *MongoStorage) GetReverseDestination(prefix string, skipCache bool) (id if err == nil { ids = result.Value } - cache2go.Set(utils.REVERSE_DESTINATION_PREFIX+prefix, ids) + cache2go.Set(utils.REVERSE_DESTINATION_PREFIX+prefix, ids, cacheCommit(transactionID), transactionID) return } -func (ms *MongoStorage) SetReverseDestination(dest *Destination) (err error) { +func (ms *MongoStorage) SetReverseDestination(dest *Destination, transactionID string) (err error) { session, col := ms.conn(colRds) defer session.Close() + cCommig := cacheCommit(transactionID) for _, p := range dest.Prefixes { _, err = col.Upsert(bson.M{"key": p}, bson.M{"$addToSet": bson.M{"value": dest.Id}}) if err != nil { break } - cache2go.RemKey(utils.REVERSE_DESTINATION_PREFIX + p) + cache2go.RemKey(utils.REVERSE_DESTINATION_PREFIX+p, cCommig, transactionID) } return } -func (ms *MongoStorage) RemoveDestination(destID string) (err error) { +func (ms *MongoStorage) RemoveDestination(destID string, transactionID string) (err error) { session, col := ms.conn(colDst) key := utils.DESTINATION_PREFIX + destID // get destination for prefix list - d, err := ms.GetDestination(destID, false) + d, err := ms.GetDestination(destID, false, transactionID) if err != nil { return } @@ -842,7 +844,7 @@ func (ms *MongoStorage) RemoveDestination(destID string) (err error) { if err != nil { return err } - cache2go.RemKey(key) + cache2go.RemKey(key, cacheCommit(transactionID), transactionID) session.Close() session, col = ms.conn(colRds) @@ -852,12 +854,12 @@ func (ms *MongoStorage) RemoveDestination(destID string) (err error) { if err != nil { return err } - ms.GetReverseDestination(prefix, true) // it will recache the destination + ms.GetReverseDestination(prefix, true, transactionID) // it will recache the destination } return } -func (ms *MongoStorage) UpdateReverseDestination(oldDest, newDest *Destination) error { +func (ms *MongoStorage) UpdateReverseDestination(oldDest, newDest *Destination, transactionID string) error { session, col := ms.conn(colRds) defer session.Close() //log.Printf("Old: %+v, New: %+v", oldDest, newDest) @@ -892,13 +894,14 @@ func (ms *MongoStorage) UpdateReverseDestination(oldDest, newDest *Destination) //log.Print("Obsolete prefixes: ", obsoletePrefixes) //log.Print("Added prefixes: ", addedPrefixes) // remove id for all obsolete prefixes + cCommit := cacheCommit(transactionID) var err error for _, obsoletePrefix := range obsoletePrefixes { err = col.Update(bson.M{"key": obsoletePrefix}, bson.M{"$pull": bson.M{"value": oldDest.Id}}) if err != nil { return err } - cache2go.RemKey(utils.REVERSE_DESTINATION_PREFIX + obsoletePrefix) + cache2go.RemKey(utils.REVERSE_DESTINATION_PREFIX+obsoletePrefix, cCommit, transactionID) } // add the id to all new prefixes @@ -907,12 +910,12 @@ func (ms *MongoStorage) UpdateReverseDestination(oldDest, newDest *Destination) if err != nil { return err } - cache2go.RemKey(utils.REVERSE_DESTINATION_PREFIX + addedPrefix) + cache2go.RemKey(utils.REVERSE_DESTINATION_PREFIX+addedPrefix, cCommit, transactionID) } return nil } -func (ms *MongoStorage) GetActions(key string, skipCache bool) (as Actions, err error) { +func (ms *MongoStorage) GetActions(key string, skipCache bool, transactionID string) (as Actions, err error) { if !skipCache { if x, ok := cache2go.Get(utils.ACTION_PREFIX + key); ok { if x != nil { @@ -931,28 +934,30 @@ func (ms *MongoStorage) GetActions(key string, skipCache bool) (as Actions, err if err == nil { as = result.Value } - cache2go.Set(utils.ACTION_PREFIX+key, as) + cache2go.Set(utils.ACTION_PREFIX+key, as, cacheCommit(transactionID), transactionID) return } -func (ms *MongoStorage) SetActions(key string, as Actions) error { +func (ms *MongoStorage) SetActions(key string, as Actions, transactionID string) error { session, col := ms.conn(colAct) defer session.Close() _, err := col.Upsert(bson.M{"key": key}, &struct { Key string Value Actions }{Key: key, Value: as}) - cache2go.RemKey(utils.ACTION_PREFIX + key) + cache2go.RemKey(utils.ACTION_PREFIX+key, cacheCommit(transactionID), transactionID) return err } -func (ms *MongoStorage) RemoveActions(key string) error { +func (ms *MongoStorage) RemoveActions(key string, transactionID string) error { session, col := ms.conn(colAct) defer session.Close() - return col.Remove(bson.M{"key": key}) + err := col.Remove(bson.M{"key": key}) + cache2go.RemKey(utils.ACTION_PREFIX+key, cacheCommit(transactionID), transactionID) + return err } -func (ms *MongoStorage) GetSharedGroup(key string, skipCache bool) (sg *SharedGroup, err error) { +func (ms *MongoStorage) GetSharedGroup(key string, skipCache bool, transactionID string) (sg *SharedGroup, err error) { if !skipCache { if x, ok := cache2go.Get(utils.SHARED_GROUP_PREFIX + key); ok { if x != nil { @@ -966,18 +971,18 @@ func (ms *MongoStorage) GetSharedGroup(key string, skipCache bool) (sg *SharedGr sg = &SharedGroup{} err = col.Find(bson.M{"id": key}).One(sg) if err == nil { - cache2go.Set(utils.SHARED_GROUP_PREFIX+key, sg) + cache2go.Set(utils.SHARED_GROUP_PREFIX+key, sg, cacheCommit(transactionID), transactionID) } else { - cache2go.Set(utils.SHARED_GROUP_PREFIX+key, nil) + cache2go.Set(utils.SHARED_GROUP_PREFIX+key, nil, cacheCommit(transactionID), transactionID) } return } -func (ms *MongoStorage) SetSharedGroup(sg *SharedGroup) (err error) { +func (ms *MongoStorage) SetSharedGroup(sg *SharedGroup, transactionID string) (err error) { session, col := ms.conn(colShg) defer session.Close() _, err = col.Upsert(bson.M{"id": sg.Id}, sg) - cache2go.RemKey(utils.SHARED_GROUP_PREFIX + sg.Id) + cache2go.RemKey(utils.SHARED_GROUP_PREFIX+sg.Id, cacheCommit(transactionID), transactionID) return err } @@ -1119,7 +1124,7 @@ func (ms *MongoStorage) RemoveUser(key string) (err error) { return col.Remove(bson.M{"key": key}) } -func (ms *MongoStorage) GetAlias(key string, skipCache bool) (al *Alias, err error) { +func (ms *MongoStorage) GetAlias(key string, skipCache bool, transactionID string) (al *Alias, err error) { origKey := key key = utils.ALIASES_PREFIX + key if !skipCache { @@ -1139,31 +1144,32 @@ func (ms *MongoStorage) GetAlias(key string, skipCache bool) (al *Alias, err err } session, col := ms.conn(colAls) defer session.Close() + cCommit := cacheCommit(transactionID) if err = col.Find(bson.M{"key": origKey}).One(&kv); err == nil { al = &Alias{Values: kv.Value} al.SetId(origKey) if err == nil { - cache2go.Set(key, al.Values) + cache2go.Set(key, al.Values, cCommit, transactionID) } } else { - cache2go.Set(key, nil) + cache2go.Set(key, nil, cCommit, transactionID) return nil, utils.ErrNotFound } return } -func (ms *MongoStorage) SetAlias(al *Alias) (err error) { +func (ms *MongoStorage) SetAlias(al *Alias, transactionID string) (err error) { session, col := ms.conn(colAls) defer session.Close() _, err = col.Upsert(bson.M{"key": al.GetId()}, &struct { Key string Value AliasValues }{Key: al.GetId(), Value: al.Values}) - cache2go.RemKey(utils.ALIASES_PREFIX + al.GetId()) + cache2go.RemKey(utils.ALIASES_PREFIX+al.GetId(), cacheCommit(transactionID), transactionID) return err } -func (ms *MongoStorage) GetReverseAlias(reverseID string, skipCache bool) (ids []string, err error) { +func (ms *MongoStorage) GetReverseAlias(reverseID string, skipCache bool, transactionID string) (ids []string, err error) { if !skipCache { if x, ok := cache2go.Get(utils.REVERSE_ALIASES_PREFIX + reverseID); ok { if x != nil { @@ -1180,18 +1186,19 @@ func (ms *MongoStorage) GetReverseAlias(reverseID string, skipCache bool) (ids [ defer session.Close() if err = col.Find(bson.M{"key": reverseID}).One(&result); err == nil { ids = result.Value - cache2go.Set(utils.REVERSE_ALIASES_PREFIX+reverseID, ids) + cache2go.Set(utils.REVERSE_ALIASES_PREFIX+reverseID, ids, cacheCommit(transactionID), transactionID) } else { - cache2go.Set(utils.REVERSE_ALIASES_PREFIX+reverseID, nil) + cache2go.Set(utils.REVERSE_ALIASES_PREFIX+reverseID, nil, cacheCommit(transactionID), transactionID) return nil, utils.ErrNotFound } return } -func (ms *MongoStorage) SetReverseAlias(al *Alias) (err error) { +func (ms *MongoStorage) SetReverseAlias(al *Alias, transactionID string) (err error) { session, col := ms.conn(colRls) defer session.Close() + cCommit := cacheCommit(transactionID) for _, value := range al.Values { for target, pairs := range value.Pairs { for _, alias := range pairs { @@ -1201,14 +1208,14 @@ func (ms *MongoStorage) SetReverseAlias(al *Alias) (err error) { if err != nil { break } - cache2go.RemKey(rKey) + cache2go.RemKey(rKey, cCommit, transactionID) } } } return } -func (ms *MongoStorage) RemoveAlias(key string) (err error) { +func (ms *MongoStorage) RemoveAlias(key, transactionID string) (err error) { al := &Alias{} al.SetId(key) origKey := key @@ -1225,7 +1232,8 @@ func (ms *MongoStorage) RemoveAlias(key string) (err error) { if err != nil { return err } - cache2go.RemKey(key) + cCommit := cacheCommit(transactionID) + cache2go.RemKey(key, cCommit, transactionID) session.Close() session, col = ms.conn(colRls) @@ -1239,19 +1247,19 @@ func (ms *MongoStorage) RemoveAlias(key string) (err error) { if err != nil { return err } - cache2go.RemKey(utils.REVERSE_ALIASES_PREFIX + rKey) + cache2go.RemKey(utils.REVERSE_ALIASES_PREFIX+rKey, cCommit, transactionID) } } } return } -func (ms *MongoStorage) UpdateReverseAlias(oldAl, newAl *Alias) error { +func (ms *MongoStorage) UpdateReverseAlias(oldAl, newAl *Alias, transactionID string) error { return nil } // Limit will only retrieve the last n items out of history, newest first -func (ms *MongoStorage) GetLoadHistory(limit int, skipCache bool) (loadInsts []*utils.LoadInstance, err error) { +func (ms *MongoStorage) GetLoadHistory(limit int, skipCache bool, transactionID string) (loadInsts []*utils.LoadInstance, err error) { if limit == 0 { return nil, nil } @@ -1274,10 +1282,11 @@ func (ms *MongoStorage) GetLoadHistory(limit int, skipCache bool) (loadInsts []* session, col := ms.conn(colLht) defer session.Close() err = col.Find(bson.M{"key": utils.LOADINST_KEY}).One(&kv) + cCommit := cacheCommit(transactionID) if err == nil { loadInsts = kv.Value - cache2go.RemKey(utils.LOADINST_KEY) - cache2go.Set(utils.LOADINST_KEY, loadInsts) + cache2go.RemKey(utils.LOADINST_KEY, cCommit, transactionID) + cache2go.Set(utils.LOADINST_KEY, loadInsts, cCommit, transactionID) } if len(loadInsts) < limit || limit == -1 { return loadInsts, nil @@ -1286,7 +1295,7 @@ func (ms *MongoStorage) GetLoadHistory(limit int, skipCache bool) (loadInsts []* } // Adds a single load instance to load history -func (ms *MongoStorage) AddLoadHistory(ldInst *utils.LoadInstance, loadHistSize int) error { +func (ms *MongoStorage) AddLoadHistory(ldInst *utils.LoadInstance, loadHistSize int, transactionID string) error { if loadHistSize == 0 { // Load history disabled return nil } @@ -1328,11 +1337,11 @@ func (ms *MongoStorage) AddLoadHistory(ldInst *utils.LoadInstance, loadHistSize return nil, err }, 0, utils.LOADINST_KEY) - cache2go.RemKey(utils.LOADINST_KEY) + cache2go.RemKey(utils.LOADINST_KEY, cacheCommit(transactionID), transactionID) return err } -func (ms *MongoStorage) GetActionTriggers(key string, skipCache bool) (atrs ActionTriggers, err error) { +func (ms *MongoStorage) GetActionTriggers(key string, skipCache bool, transactionID string) (atrs ActionTriggers, err error) { if !skipCache { if x, ok := cache2go.Get(utils.ACTION_TRIGGER_PREFIX + key); ok { if x != nil { @@ -1352,11 +1361,11 @@ func (ms *MongoStorage) GetActionTriggers(key string, skipCache bool) (atrs Acti if err == nil { atrs = kv.Value } - cache2go.Set(utils.ACTION_TRIGGER_PREFIX+key, atrs) + cache2go.Set(utils.ACTION_TRIGGER_PREFIX+key, atrs, cacheCommit(transactionID), transactionID) return } -func (ms *MongoStorage) SetActionTriggers(key string, atrs ActionTriggers) (err error) { +func (ms *MongoStorage) SetActionTriggers(key string, atrs ActionTriggers, transactionID string) (err error) { session, col := ms.conn(colAtr) defer session.Close() if len(atrs) == 0 { @@ -1370,21 +1379,21 @@ func (ms *MongoStorage) SetActionTriggers(key string, atrs ActionTriggers) (err Key string Value ActionTriggers }{Key: key, Value: atrs}) - cache2go.RemKey(utils.ACTION_TRIGGER_PREFIX + key) + cache2go.RemKey(utils.ACTION_TRIGGER_PREFIX+key, cacheCommit(transactionID), transactionID) return err } -func (ms *MongoStorage) RemoveActionTriggers(key string) error { +func (ms *MongoStorage) RemoveActionTriggers(key string, transactionID string) error { session, col := ms.conn(colAtr) defer session.Close() err := col.Remove(bson.M{"key": key}) if err == nil { - cache2go.RemKey(key) + cache2go.RemKey(key, cacheCommit(transactionID), transactionID) } return err } -func (ms *MongoStorage) GetActionPlan(key string, skipCache bool) (ats *ActionPlan, err error) { +func (ms *MongoStorage) GetActionPlan(key string, skipCache bool, transactionID string) (ats *ActionPlan, err error) { if !skipCache { if x, ok := cache2go.Get(utils.ACTION_PLAN_PREFIX + key); ok { if x != nil { @@ -1416,16 +1425,17 @@ func (ms *MongoStorage) GetActionPlan(key string, skipCache bool) (ats *ActionPl return nil, err } } - cache2go.Set(utils.ACTION_PLAN_PREFIX+key, ats) + cache2go.Set(utils.ACTION_PLAN_PREFIX+key, ats, cacheCommit(transactionID), transactionID) return } -func (ms *MongoStorage) SetActionPlan(key string, ats *ActionPlan, overwrite bool) error { +func (ms *MongoStorage) SetActionPlan(key string, ats *ActionPlan, overwrite bool, transactionID string) error { session, col := ms.conn(colApl) defer session.Close() // clean dots from account ids map + cCommit := cacheCommit(transactionID) if len(ats.ActionTimings) == 0 { - cache2go.RemKey(utils.ACTION_PLAN_PREFIX + key) + cache2go.RemKey(utils.ACTION_PLAN_PREFIX+key, cCommit, transactionID) err := col.Remove(bson.M{"key": key}) if err != mgo.ErrNotFound { return err @@ -1434,7 +1444,7 @@ func (ms *MongoStorage) SetActionPlan(key string, ats *ActionPlan, overwrite boo } if !overwrite { // get existing action plan to merge the account ids - if existingAts, _ := ms.GetActionPlan(key, true); existingAts != nil { + if existingAts, _ := ms.GetActionPlan(key, true, transactionID); existingAts != nil { if ats.AccountIDs == nil && len(existingAts.AccountIDs) > 0 { ats.AccountIDs = make(utils.StringMap) } @@ -1455,7 +1465,7 @@ func (ms *MongoStorage) SetActionPlan(key string, ats *ActionPlan, overwrite boo Key string Value []byte }{Key: key, Value: b.Bytes()}) - cache2go.RemKey(utils.ACTION_PLAN_PREFIX + key) + cache2go.RemKey(utils.ACTION_PLAN_PREFIX+key, cCommit, transactionID) return err } @@ -1467,7 +1477,7 @@ func (ms *MongoStorage) GetAllActionPlans() (ats map[string]*ActionPlan, err err ats = make(map[string]*ActionPlan, len(keys)) for _, key := range keys { - ap, err := ms.GetActionPlan(key[len(utils.ACTION_PLAN_PREFIX):], false) + ap, err := ms.GetActionPlan(key[len(utils.ACTION_PLAN_PREFIX):], false, utils.NonTransactional) if err != nil { return nil, err } @@ -1500,7 +1510,7 @@ func (ms *MongoStorage) PopTask() (t *Task, err error) { return } -func (ms *MongoStorage) GetDerivedChargers(key string, skipCache bool) (dcs *utils.DerivedChargers, err error) { +func (ms *MongoStorage) GetDerivedChargers(key string, skipCache bool, transactionID string) (dcs *utils.DerivedChargers, err error) { if !skipCache { if x, ok := cache2go.Get(utils.DERIVEDCHARGERS_PREFIX + key); ok { if x != nil { @@ -1516,19 +1526,21 @@ func (ms *MongoStorage) GetDerivedChargers(key string, skipCache bool) (dcs *uti session, col := ms.conn(colDcs) defer session.Close() err = col.Find(bson.M{"key": key}).One(&kv) + cCommit := cacheCommit(transactionID) if err == nil { dcs = kv.Value } else { - cache2go.Set(utils.DERIVEDCHARGERS_PREFIX+key, nil) + cache2go.Set(utils.DERIVEDCHARGERS_PREFIX+key, nil, cCommit, transactionID) return nil, utils.ErrNotFound } - cache2go.Set(utils.DERIVEDCHARGERS_PREFIX+key, dcs) + cache2go.Set(utils.DERIVEDCHARGERS_PREFIX+key, dcs, cCommit, transactionID) return } -func (ms *MongoStorage) SetDerivedChargers(key string, dcs *utils.DerivedChargers) (err error) { +func (ms *MongoStorage) SetDerivedChargers(key string, dcs *utils.DerivedChargers, transactionID string) (err error) { + cCommit := cacheCommit(transactionID) if dcs == nil || len(dcs.Chargers) == 0 { - cache2go.RemKey(utils.DERIVEDCHARGERS_PREFIX + key) + cache2go.RemKey(utils.DERIVEDCHARGERS_PREFIX+key, cCommit, transactionID) session, col := ms.conn(colDcs) defer session.Close() err = col.Remove(bson.M{"key": key}) @@ -1543,7 +1555,7 @@ func (ms *MongoStorage) SetDerivedChargers(key string, dcs *utils.DerivedCharger Key string Value *utils.DerivedChargers }{Key: key, Value: dcs}) - cache2go.RemKey(utils.DERIVEDCHARGERS_PREFIX + key) + cache2go.RemKey(utils.DERIVEDCHARGERS_PREFIX+key, cCommit, transactionID) return err } @@ -1600,12 +1612,12 @@ func (ms *MongoStorage) GetStructVersion() (rsv *StructVersion, err error) { return } -func (ms *MongoStorage) GetResourceLimit(id string, skipCache bool) (*ResourceLimit, error) { +func (ms *MongoStorage) GetResourceLimit(id string, skipCache bool, transactionID string) (*ResourceLimit, error) { return nil, nil } -func (ms *MongoStorage) SetResourceLimit(rl *ResourceLimit) error { +func (ms *MongoStorage) SetResourceLimit(rl *ResourceLimit, transactionID string) error { return nil } -func (ms *MongoStorage) RemoveResourceLimit(id string) error { +func (ms *MongoStorage) RemoveResourceLimit(id string, transactionID string) error { return nil } diff --git a/engine/storage_redis.go b/engine/storage_redis.go index 9c69143fb..d5c6f4b42 100644 --- a/engine/storage_redis.go +++ b/engine/storage_redis.go @@ -167,34 +167,34 @@ func (rs *RedisStorage) PreloadAccountingCache() error { } func (rs *RedisStorage) PreloadCacheForPrefix(prefix string) error { - cache2go.BeginTransaction() - cache2go.RemPrefixKey(prefix) + transID := cache2go.BeginTransaction() + cache2go.RemPrefixKey(prefix, false, transID) keyList, err := rs.GetKeysForPrefix(prefix) if err != nil { - cache2go.RollbackTransaction() + cache2go.RollbackTransaction(transID) return err } switch prefix { case utils.RATING_PLAN_PREFIX: for _, key := range keyList { - _, err := rs.GetRatingPlan(key[len(utils.RATING_PLAN_PREFIX):], true) + _, err := rs.GetRatingPlan(key[len(utils.RATING_PLAN_PREFIX):], true, transID) if err != nil { - cache2go.RollbackTransaction() + cache2go.RollbackTransaction(transID) return err } } case utils.ResourceLimitsPrefix: for _, key := range keyList { - _, err = rs.GetResourceLimit(key[len(utils.ResourceLimitsPrefix):], true) + _, err = rs.GetResourceLimit(key[len(utils.ResourceLimitsPrefix):], true, transID) if err != nil { - cache2go.RollbackTransaction() + cache2go.RollbackTransaction(transID) return err } } default: return utils.ErrInvalidKey } - cache2go.CommitTransaction() + cache2go.CommitTransaction(transID) return nil } @@ -221,11 +221,11 @@ func (rs *RedisStorage) RebuildReverseForPrefix(prefix string) error { return err } for _, key := range keys { - dest, err := rs.GetDestination(key[len(utils.DESTINATION_PREFIX):], false) + dest, err := rs.GetDestination(key[len(utils.DESTINATION_PREFIX):], false, utils.NonTransactional) if err != nil { return err } - if err := rs.SetReverseDestination(dest); err != nil { + if err := rs.SetReverseDestination(dest, utils.NonTransactional); err != nil { return err } } @@ -235,11 +235,11 @@ func (rs *RedisStorage) RebuildReverseForPrefix(prefix string) error { return err } for _, key := range keys { - al, err := rs.GetAlias(key[len(utils.ALIASES_PREFIX):], false) + al, err := rs.GetAlias(key[len(utils.ALIASES_PREFIX):], false, utils.NonTransactional) if err != nil { return err } - if err := rs.SetReverseAlias(al); err != nil { + if err := rs.SetReverseAlias(al, utils.NonTransactional); err != nil { return err } } @@ -267,7 +267,7 @@ func (rs *RedisStorage) HasData(category, subject string) (bool, error) { return false, errors.New("unsupported HasData category") } -func (rs *RedisStorage) GetRatingPlan(key string, skipCache bool) (rp *RatingPlan, err error) { +func (rs *RedisStorage) GetRatingPlan(key string, skipCache bool, transactionID string) (rp *RatingPlan, err error) { key = utils.RATING_PLAN_PREFIX + key if !skipCache { if x, ok := cache2go.Get(key); ok { @@ -292,11 +292,11 @@ func (rs *RedisStorage) GetRatingPlan(key string, skipCache bool) (rp *RatingPla rp = new(RatingPlan) err = rs.ms.Unmarshal(out, rp) } - cache2go.Set(key, rp) + cache2go.Set(key, rp, cacheCommit(transactionID), transactionID) return } -func (rs *RedisStorage) SetRatingPlan(rp *RatingPlan) (err error) { +func (rs *RedisStorage) SetRatingPlan(rp *RatingPlan, transactionID string) (err error) { result, err := rs.ms.Marshal(rp) var b bytes.Buffer w := zlib.NewWriter(&b) @@ -307,11 +307,11 @@ func (rs *RedisStorage) SetRatingPlan(rp *RatingPlan) (err error) { response := 0 go historyScribe.Call("HistoryV1.Record", rp.GetHistoryRecord(), &response) } - cache2go.Set(utils.RATING_PLAN_PREFIX+rp.Id, rp) + cache2go.Set(utils.RATING_PLAN_PREFIX+rp.Id, rp, cacheCommit(transactionID), transactionID) return } -func (rs *RedisStorage) GetRatingProfile(key string, skipCache bool) (rpf *RatingProfile, err error) { +func (rs *RedisStorage) GetRatingProfile(key string, skipCache bool, transactionID string) (rpf *RatingProfile, err error) { key = utils.RATING_PROFILE_PREFIX + key if !skipCache { @@ -327,22 +327,22 @@ func (rs *RedisStorage) GetRatingProfile(key string, skipCache bool) (rpf *Ratin rpf = new(RatingProfile) err = rs.ms.Unmarshal(values, rpf) } - cache2go.Set(key, rpf) + cache2go.Set(key, rpf, cacheCommit(transactionID), transactionID) return } -func (rs *RedisStorage) SetRatingProfile(rpf *RatingProfile) (err error) { +func (rs *RedisStorage) SetRatingProfile(rpf *RatingProfile, transactionID string) (err error) { result, err := rs.ms.Marshal(rpf) err = rs.db.Cmd("SET", utils.RATING_PROFILE_PREFIX+rpf.Id, result).Err if err == nil && historyScribe != nil { response := 0 go historyScribe.Call("HistoryV1.Record", rpf.GetHistoryRecord(false), &response) } - cache2go.RemKey(utils.RATING_PROFILE_PREFIX + rpf.Id) + cache2go.RemKey(utils.RATING_PROFILE_PREFIX+rpf.Id, cacheCommit(transactionID), transactionID) return } -func (rs *RedisStorage) RemoveRatingProfile(key string) error { +func (rs *RedisStorage) RemoveRatingProfile(key string, transactionID string) error { conn, err := rs.db.Get() if err != nil { return err @@ -356,7 +356,7 @@ func (rs *RedisStorage) RemoveRatingProfile(key string) error { if err = conn.Cmd("DEL", key).Err; err != nil { return err } - cache2go.RemKey(key) + cache2go.RemKey(key, cacheCommit(transactionID), transactionID) rpf := &RatingProfile{Id: key} if historyScribe != nil { response := 0 @@ -366,7 +366,7 @@ func (rs *RedisStorage) RemoveRatingProfile(key string) error { return nil } -func (rs *RedisStorage) GetLCR(key string, skipCache bool) (lcr *LCR, err error) { +func (rs *RedisStorage) GetLCR(key string, skipCache bool, transactionID string) (lcr *LCR, err error) { key = utils.LCR_PREFIX + key if !skipCache { if x, ok := cache2go.Get(key); ok { @@ -381,22 +381,22 @@ func (rs *RedisStorage) GetLCR(key string, skipCache bool) (lcr *LCR, err error) if values, err = rs.db.Cmd("GET", key).Bytes(); err == nil { err = rs.ms.Unmarshal(values, &lcr) } else { - cache2go.Set(key, nil) + cache2go.Set(key, nil, cacheCommit(transactionID), transactionID) return nil, utils.ErrNotFound } - cache2go.Set(key, lcr) + cache2go.Set(key, lcr, cacheCommit(transactionID), transactionID) return } -func (rs *RedisStorage) SetLCR(lcr *LCR) (err error) { +func (rs *RedisStorage) SetLCR(lcr *LCR, transactionID string) (err error) { result, err := rs.ms.Marshal(lcr) key := utils.LCR_PREFIX + lcr.GetId() err = rs.db.Cmd("SET", key, result).Err - cache2go.RemKey(key) + cache2go.RemKey(key, cacheCommit(transactionID), transactionID) return } -func (rs *RedisStorage) GetDestination(key string, skipCache bool) (dest *Destination, err error) { +func (rs *RedisStorage) GetDestination(key string, skipCache bool, transactionID string) (dest *Destination, err error) { key = utils.DESTINATION_PREFIX + key if !skipCache { if x, ok := cache2go.Get(key); ok { @@ -421,16 +421,16 @@ func (rs *RedisStorage) GetDestination(key string, skipCache bool) (dest *Destin dest = new(Destination) err = rs.ms.Unmarshal(out, dest) if err != nil { - cache2go.Set(key, dest) + cache2go.Set(key, dest, cacheCommit(transactionID), transactionID) } } else { - cache2go.Set(key, nil) + cache2go.Set(key, nil, cacheCommit(transactionID), transactionID) return nil, err } return } -func (rs *RedisStorage) SetDestination(dest *Destination) (err error) { +func (rs *RedisStorage) SetDestination(dest *Destination, transactionID string) (err error) { result, err := rs.ms.Marshal(dest) if err != nil { return err @@ -445,11 +445,11 @@ func (rs *RedisStorage) SetDestination(dest *Destination) (err error) { response := 0 go historyScribe.Call("HistoryV1.Record", dest.GetHistoryRecord(false), &response) } - cache2go.RemKey(key) + cache2go.RemKey(key, cacheCommit(transactionID), transactionID) return } -func (rs *RedisStorage) GetReverseDestination(prefix string, skipCache bool) (ids []string, err error) { +func (rs *RedisStorage) GetReverseDestination(prefix string, skipCache bool, transactionID string) (ids []string, err error) { prefix = utils.REVERSE_DESTINATION_PREFIX + prefix if !skipCache { if x, ok := cache2go.Get(prefix); ok { @@ -460,28 +460,28 @@ func (rs *RedisStorage) GetReverseDestination(prefix string, skipCache bool) (id } } if ids, err = rs.db.Cmd("SMEMBERS", prefix).List(); len(ids) > 0 && err == nil { - cache2go.Set(prefix, ids) + cache2go.Set(prefix, ids, cacheCommit(transactionID), transactionID) return ids, nil } return nil, utils.ErrNotFound } -func (rs *RedisStorage) SetReverseDestination(dest *Destination) (err error) { +func (rs *RedisStorage) SetReverseDestination(dest *Destination, transactionID string) (err error) { for _, p := range dest.Prefixes { key := utils.REVERSE_DESTINATION_PREFIX + p err = rs.db.Cmd("SADD", key, dest.Id).Err if err != nil { break } - cache2go.RemKey(key) + cache2go.RemKey(key, cacheCommit(transactionID), transactionID) } return } -func (rs *RedisStorage) RemoveDestination(destID string) (err error) { +func (rs *RedisStorage) RemoveDestination(destID, transactionID string) (err error) { key := utils.DESTINATION_PREFIX + destID // get destination for prefix list - d, err := rs.GetDestination(destID, false) + d, err := rs.GetDestination(destID, false, transactionID) if err != nil { return } @@ -489,18 +489,18 @@ func (rs *RedisStorage) RemoveDestination(destID string) (err error) { if err != nil { return err } - cache2go.RemKey(key) + cache2go.RemKey(key, cacheCommit(transactionID), transactionID) for _, prefix := range d.Prefixes { err = rs.db.Cmd("SREM", utils.REVERSE_DESTINATION_PREFIX+prefix, destID).Err if err != nil { return err } - rs.GetReverseDestination(prefix, true) // it will recache the destination + rs.GetReverseDestination(prefix, true, transactionID) // it will recache the destination } return } -func (rs *RedisStorage) UpdateReverseDestination(oldDest, newDest *Destination) error { +func (rs *RedisStorage) UpdateReverseDestination(oldDest, newDest *Destination, transactionID string) error { //log.Printf("Old: %+v, New: %+v", oldDest, newDest) var obsoletePrefixes []string var addedPrefixes []string @@ -533,13 +533,14 @@ func (rs *RedisStorage) UpdateReverseDestination(oldDest, newDest *Destination) //log.Print("Obsolete prefixes: ", obsoletePrefixes) //log.Print("Added prefixes: ", addedPrefixes) // remove id for all obsolete prefixes + cCommit := cacheCommit(transactionID) var err error for _, obsoletePrefix := range obsoletePrefixes { err = rs.db.Cmd("SREM", utils.REVERSE_DESTINATION_PREFIX+obsoletePrefix, oldDest.Id).Err if err != nil { return err } - cache2go.RemKey(utils.REVERSE_DESTINATION_PREFIX + obsoletePrefix) + cache2go.RemKey(utils.REVERSE_DESTINATION_PREFIX+obsoletePrefix, cCommit, transactionID) } // add the id to all new prefixes @@ -548,12 +549,12 @@ func (rs *RedisStorage) UpdateReverseDestination(oldDest, newDest *Destination) if err != nil { return err } - cache2go.RemKey(utils.REVERSE_DESTINATION_PREFIX + addedPrefix) + cache2go.RemKey(utils.REVERSE_DESTINATION_PREFIX+addedPrefix, cCommit, transactionID) } return nil } -func (rs *RedisStorage) GetActions(key string, skipCache bool) (as Actions, err error) { +func (rs *RedisStorage) GetActions(key string, skipCache bool, transactionID string) (as Actions, err error) { key = utils.ACTION_PREFIX + key if !skipCache { if x, ok := cache2go.Get(key); ok { @@ -567,24 +568,24 @@ func (rs *RedisStorage) GetActions(key string, skipCache bool) (as Actions, err if values, err = rs.db.Cmd("GET", key).Bytes(); err == nil { err = rs.ms.Unmarshal(values, &as) } - cache2go.Set(key, as) + cache2go.Set(key, as, cacheCommit(transactionID), transactionID) return } -func (rs *RedisStorage) SetActions(key string, as Actions) (err error) { +func (rs *RedisStorage) SetActions(key string, as Actions, transactionID string) (err error) { result, err := rs.ms.Marshal(&as) err = rs.db.Cmd("SET", utils.ACTION_PREFIX+key, result).Err - cache2go.RemKey(utils.ACTION_PREFIX + key) + cache2go.RemKey(utils.ACTION_PREFIX+key, cacheCommit(transactionID), transactionID) return } -func (rs *RedisStorage) RemoveActions(key string) (err error) { +func (rs *RedisStorage) RemoveActions(key string, transactionID string) (err error) { err = rs.db.Cmd("DEL", utils.ACTION_PREFIX+key).Err - cache2go.RemKey(utils.ACTION_PREFIX + key) + cache2go.RemKey(utils.ACTION_PREFIX+key, cacheCommit(transactionID), transactionID) return } -func (rs *RedisStorage) GetSharedGroup(key string, skipCache bool) (sg *SharedGroup, err error) { +func (rs *RedisStorage) GetSharedGroup(key string, skipCache bool, transactionID string) (sg *SharedGroup, err error) { key = utils.SHARED_GROUP_PREFIX + key if !skipCache { if x, ok := cache2go.Get(key); ok { @@ -598,14 +599,14 @@ func (rs *RedisStorage) GetSharedGroup(key string, skipCache bool) (sg *SharedGr if values, err = rs.db.Cmd("GET", key).Bytes(); err == nil { err = rs.ms.Unmarshal(values, &sg) } - cache2go.Set(key, sg) + cache2go.Set(key, sg, cacheCommit(transactionID), transactionID) return } -func (rs *RedisStorage) SetSharedGroup(sg *SharedGroup) (err error) { +func (rs *RedisStorage) SetSharedGroup(sg *SharedGroup, transactionID string) (err error) { result, err := rs.ms.Marshal(sg) err = rs.db.Cmd("SET", utils.SHARED_GROUP_PREFIX+sg.Id, result).Err - cache2go.RemKey(utils.SHARED_GROUP_PREFIX + sg.Id) + cache2go.RemKey(utils.SHARED_GROUP_PREFIX+sg.Id, cacheCommit(transactionID), transactionID) return } @@ -744,7 +745,7 @@ func (rs *RedisStorage) RemoveUser(key string) (err error) { return rs.db.Cmd("DEL", utils.USERS_PREFIX+key).Err } -func (rs *RedisStorage) GetAlias(key string, skipCache bool) (al *Alias, err error) { +func (rs *RedisStorage) GetAlias(key string, skipCache bool, transactionID string) (al *Alias, err error) { origKey := key key = utils.ALIASES_PREFIX + key @@ -764,25 +765,25 @@ func (rs *RedisStorage) GetAlias(key string, skipCache bool) (al *Alias, err err al.SetId(origKey) err = rs.ms.Unmarshal(values, &al.Values) } else { - cache2go.Set(key, nil) + cache2go.Set(key, nil, cacheCommit(transactionID), transactionID) return nil, utils.ErrNotFound } - cache2go.Set(key, al.Values) + cache2go.Set(key, al.Values, cacheCommit(transactionID), transactionID) return } -func (rs *RedisStorage) SetAlias(al *Alias) (err error) { +func (rs *RedisStorage) SetAlias(al *Alias, transactionID string) (err error) { result, err := rs.ms.Marshal(al.Values) if err != nil { return err } key := utils.ALIASES_PREFIX + al.GetId() err = rs.db.Cmd("SET", key, result).Err - cache2go.RemKey(key) + cache2go.RemKey(key, cacheCommit(transactionID), transactionID) return } -func (rs *RedisStorage) GetReverseAlias(reverseID string, skipCache bool) (ids []string, err error) { +func (rs *RedisStorage) GetReverseAlias(reverseID string, skipCache bool, transactionID string) (ids []string, err error) { key := utils.REVERSE_ALIASES_PREFIX + reverseID if !skipCache { if x, ok := cache2go.Get(key); ok { @@ -793,14 +794,15 @@ func (rs *RedisStorage) GetReverseAlias(reverseID string, skipCache bool) (ids [ } } if ids, err = rs.db.Cmd("SMEMBERS", key).List(); len(ids) == 0 || err != nil { - cache2go.Set(key, nil) + cache2go.Set(key, nil, cacheCommit(transactionID), transactionID) return nil, utils.ErrNotFound } - cache2go.Set(key, ids) + cache2go.Set(key, ids, cacheCommit(transactionID), transactionID) return } -func (rs *RedisStorage) SetReverseAlias(al *Alias) (err error) { +func (rs *RedisStorage) SetReverseAlias(al *Alias, transactionID string) (err error) { + cCommit := cacheCommit(transactionID) for _, value := range al.Values { for target, pairs := range value.Pairs { for _, alias := range pairs { @@ -810,7 +812,7 @@ func (rs *RedisStorage) SetReverseAlias(al *Alias) (err error) { if err != nil { break } - cache2go.RemKey(rKey) + cache2go.RemKey(rKey, cCommit, transactionID) } } } @@ -818,10 +820,10 @@ func (rs *RedisStorage) SetReverseAlias(al *Alias) (err error) { return } -func (rs *RedisStorage) RemoveAlias(id string) (err error) { +func (rs *RedisStorage) RemoveAlias(id string, transactionID string) (err error) { key := utils.ALIASES_PREFIX + id // get alias for values list - al, err := rs.GetAlias(id, false) + al, err := rs.GetAlias(id, false, transactionID) if err != nil { return } @@ -829,7 +831,8 @@ func (rs *RedisStorage) RemoveAlias(id string) (err error) { if err != nil { return err } - cache2go.RemKey(key) + cCommit := cacheCommit(transactionID) + cache2go.RemKey(key, cCommit, transactionID) for _, value := range al.Values { tmpKey := utils.ConcatenatedKey(al.GetId(), value.DestinationId) @@ -840,7 +843,7 @@ func (rs *RedisStorage) RemoveAlias(id string) (err error) { if err != nil { return err } - cache2go.RemKey(rKey) + cache2go.RemKey(rKey, cCommit, transactionID) /*_, err = rs.GetReverseAlias(rKey, true) // recache if err != nil { return err @@ -851,15 +854,15 @@ func (rs *RedisStorage) RemoveAlias(id string) (err error) { return } -func (rs *RedisStorage) UpdateReverseAlias(oldAl, newAl *Alias) error { +func (rs *RedisStorage) UpdateReverseAlias(oldAl, newAl *Alias, transactionID string) error { // FIXME: thi can be optimized - cache2go.RemPrefixKey(utils.REVERSE_ALIASES_PREFIX) - rs.SetReverseAlias(newAl) + cache2go.RemPrefixKey(utils.REVERSE_ALIASES_PREFIX, cacheCommit(transactionID), transactionID) + rs.SetReverseAlias(newAl, transactionID) return nil } // Limit will only retrieve the last n items out of history, newest first -func (rs *RedisStorage) GetLoadHistory(limit int, skipCache bool) ([]*utils.LoadInstance, error) { +func (rs *RedisStorage) GetLoadHistory(limit int, skipCache bool, transactionID string) ([]*utils.LoadInstance, error) { if limit == 0 { return nil, nil } @@ -880,8 +883,9 @@ func (rs *RedisStorage) GetLoadHistory(limit int, skipCache bool) ([]*utils.Load limit -= -1 // Decrease limit to match redis approach on lrange } marshaleds, err := rs.db.Cmd("LRANGE", utils.LOADINST_KEY, 0, limit).ListBytes() + cCommit := cacheCommit(transactionID) if err != nil { - cache2go.Set(utils.LOADINST_KEY, nil) + cache2go.Set(utils.LOADINST_KEY, nil, cCommit, transactionID) return nil, err } loadInsts := make([]*utils.LoadInstance, len(marshaleds)) @@ -893,8 +897,8 @@ func (rs *RedisStorage) GetLoadHistory(limit int, skipCache bool) ([]*utils.Load } loadInsts[idx] = &lInst } - cache2go.RemKey(utils.LOADINST_KEY) - cache2go.Set(utils.LOADINST_KEY, loadInsts) + cache2go.RemKey(utils.LOADINST_KEY, cCommit, transactionID) + cache2go.Set(utils.LOADINST_KEY, loadInsts, cCommit, transactionID) if len(loadInsts) < limit || limit == -1 { return loadInsts, nil } @@ -902,7 +906,7 @@ func (rs *RedisStorage) GetLoadHistory(limit int, skipCache bool) ([]*utils.Load } // Adds a single load instance to load history -func (rs *RedisStorage) AddLoadHistory(ldInst *utils.LoadInstance, loadHistSize int) error { +func (rs *RedisStorage) AddLoadHistory(ldInst *utils.LoadInstance, loadHistSize int, transactionID string) error { conn, err := rs.db.Get() if err != nil { return err @@ -929,11 +933,11 @@ func (rs *RedisStorage) AddLoadHistory(ldInst *utils.LoadInstance, loadHistSize return nil, err }, 0, utils.LOADINST_KEY) - cache2go.RemKey(utils.LOADINST_KEY) + cache2go.RemKey(utils.LOADINST_KEY, cacheCommit(transactionID), transactionID) return err } -func (rs *RedisStorage) GetActionTriggers(key string, skipCache bool) (atrs ActionTriggers, err error) { +func (rs *RedisStorage) GetActionTriggers(key string, skipCache bool, transactionID string) (atrs ActionTriggers, err error) { key = utils.ACTION_TRIGGER_PREFIX + key if !skipCache { if x, ok := cache2go.Get(key); ok { @@ -947,11 +951,11 @@ func (rs *RedisStorage) GetActionTriggers(key string, skipCache bool) (atrs Acti if values, err = rs.db.Cmd("GET", key).Bytes(); err == nil { err = rs.ms.Unmarshal(values, &atrs) } - cache2go.Set(key, atrs) + cache2go.Set(key, atrs, cacheCommit(transactionID), transactionID) return } -func (rs *RedisStorage) SetActionTriggers(key string, atrs ActionTriggers) (err error) { +func (rs *RedisStorage) SetActionTriggers(key string, atrs ActionTriggers, transactionID string) (err error) { conn, err := rs.db.Get() if err != nil { return err @@ -966,19 +970,19 @@ func (rs *RedisStorage) SetActionTriggers(key string, atrs ActionTriggers) (err return err } err = conn.Cmd("SET", utils.ACTION_TRIGGER_PREFIX+key, result).Err - cache2go.RemKey(utils.ACTION_TRIGGER_PREFIX + key) + cache2go.RemKey(utils.ACTION_TRIGGER_PREFIX+key, cacheCommit(transactionID), transactionID) return } -func (rs *RedisStorage) RemoveActionTriggers(key string) (err error) { +func (rs *RedisStorage) RemoveActionTriggers(key string, transactionID string) (err error) { key = utils.ACTION_TRIGGER_PREFIX + key err = rs.db.Cmd("DEL", key).Err - cache2go.RemKey(key) + cache2go.RemKey(key, cacheCommit(transactionID), transactionID) return } -func (rs *RedisStorage) GetActionPlan(key string, skipCache bool) (ats *ActionPlan, err error) { +func (rs *RedisStorage) GetActionPlan(key string, skipCache bool, transactionID string) (ats *ActionPlan, err error) { key = utils.ACTION_PLAN_PREFIX + key if !skipCache { if x, ok := cache2go.Get(key); ok { @@ -1003,20 +1007,21 @@ func (rs *RedisStorage) GetActionPlan(key string, skipCache bool) (ats *ActionPl ats = &ActionPlan{} err = rs.ms.Unmarshal(out, &ats) } - cache2go.Set(key, ats) + cache2go.Set(key, ats, cacheCommit(transactionID), transactionID) return } -func (rs *RedisStorage) SetActionPlan(key string, ats *ActionPlan, overwrite bool) (err error) { +func (rs *RedisStorage) SetActionPlan(key string, ats *ActionPlan, overwrite bool, transactionID string) (err error) { + cCommit := cacheCommit(transactionID) if len(ats.ActionTimings) == 0 { // delete the key err = rs.db.Cmd("DEL", utils.ACTION_PLAN_PREFIX+key).Err - cache2go.RemKey(utils.ACTION_PLAN_PREFIX + key) + cache2go.RemKey(utils.ACTION_PLAN_PREFIX+key, cCommit, transactionID) return err } if !overwrite { // get existing action plan to merge the account ids - if existingAts, _ := rs.GetActionPlan(key, true); existingAts != nil { + if existingAts, _ := rs.GetActionPlan(key, true, transactionID); existingAts != nil { if ats.AccountIDs == nil && len(existingAts.AccountIDs) > 0 { ats.AccountIDs = make(utils.StringMap) } @@ -1025,7 +1030,7 @@ func (rs *RedisStorage) SetActionPlan(key string, ats *ActionPlan, overwrite boo } } // do not keep this in cache (will be obsolete) - cache2go.RemKey(utils.ACTION_PLAN_PREFIX + key) + cache2go.RemKey(utils.ACTION_PLAN_PREFIX+key, cCommit, transactionID) } result, err := rs.ms.Marshal(ats) if err != nil { @@ -1036,7 +1041,7 @@ func (rs *RedisStorage) SetActionPlan(key string, ats *ActionPlan, overwrite boo w.Write(result) w.Close() err = rs.db.Cmd("SET", utils.ACTION_PLAN_PREFIX+key, b.Bytes()).Err - cache2go.RemKey(utils.ACTION_PLAN_PREFIX + key) + cache2go.RemKey(utils.ACTION_PLAN_PREFIX+key, cCommit, transactionID) return } @@ -1049,7 +1054,7 @@ func (rs *RedisStorage) GetAllActionPlans() (ats map[string]*ActionPlan, err err ats = make(map[string]*ActionPlan, len(keys)) for _, key := range keys { - ap, err := rs.GetActionPlan(key[len(utils.ACTION_PLAN_PREFIX):], false) + ap, err := rs.GetActionPlan(key[len(utils.ACTION_PLAN_PREFIX):], false, utils.NonTransactional) if err != nil { return nil, err } @@ -1076,7 +1081,7 @@ func (rs *RedisStorage) PopTask() (t *Task, err error) { return } -func (rs *RedisStorage) GetDerivedChargers(key string, skipCache bool) (dcs *utils.DerivedChargers, err error) { +func (rs *RedisStorage) GetDerivedChargers(key string, skipCache bool, transactionID string) (dcs *utils.DerivedChargers, err error) { key = utils.DERIVEDCHARGERS_PREFIX + key if !skipCache { if x, ok := cache2go.Get(key); ok { @@ -1090,18 +1095,19 @@ func (rs *RedisStorage) GetDerivedChargers(key string, skipCache bool) (dcs *uti if values, err = rs.db.Cmd("GET", key).Bytes(); err == nil { err = rs.ms.Unmarshal(values, &dcs) } else { - cache2go.Set(key, nil) + cache2go.Set(key, nil, cacheCommit(transactionID), transactionID) return nil, utils.ErrNotFound } - cache2go.Set(key, dcs) + cache2go.Set(key, dcs, cacheCommit(transactionID), transactionID) return } -func (rs *RedisStorage) SetDerivedChargers(key string, dcs *utils.DerivedChargers) (err error) { +func (rs *RedisStorage) SetDerivedChargers(key string, dcs *utils.DerivedChargers, transactionID string) (err error) { key = utils.DERIVEDCHARGERS_PREFIX + key + cCommit := cacheCommit(transactionID) if dcs == nil || len(dcs.Chargers) == 0 { err = rs.db.Cmd("DEL", key).Err - cache2go.RemKey(key) + cache2go.RemKey(key, cCommit, transactionID) return err } marshaled, err := rs.ms.Marshal(dcs) @@ -1109,7 +1115,7 @@ func (rs *RedisStorage) SetDerivedChargers(key string, dcs *utils.DerivedCharger return err } err = rs.db.Cmd("SET", key, marshaled).Err - cache2go.RemKey(key) + cache2go.RemKey(key, cCommit, transactionID) return } @@ -1169,9 +1175,8 @@ func (rs *RedisStorage) GetStructVersion() (rsv *StructVersion, err error) { return } -func (rs *RedisStorage) GetResourceLimit(id string, skipCache bool) (rl *ResourceLimit, err error) { +func (rs *RedisStorage) GetResourceLimit(id string, skipCache bool, transactionID string) (rl *ResourceLimit, err error) { key := utils.ResourceLimitsPrefix + id - if !skipCache { if x, ok := cache2go.Get(key); ok { if x != nil { @@ -1188,26 +1193,25 @@ func (rs *RedisStorage) GetResourceLimit(id string, skipCache bool) (rl *Resourc return nil, err } } - - cache2go.Set(key, rl) + cache2go.Set(key, rl, cacheCommit(transactionID), transactionID) } return } -func (rs *RedisStorage) SetResourceLimit(rl *ResourceLimit) error { +func (rs *RedisStorage) SetResourceLimit(rl *ResourceLimit, transactionID string) error { result, err := rs.ms.Marshal(rl) if err != nil { return err } key := utils.ResourceLimitsPrefix + rl.ID err = rs.db.Cmd("SET", key, result).Err - //cache2go.Set(key, rl) + cache2go.Set(key, rl, cacheCommit(transactionID), transactionID) return err } -func (rs *RedisStorage) RemoveResourceLimit(id string) error { +func (rs *RedisStorage) RemoveResourceLimit(id string, transactionID string) error { key := utils.ResourceLimitsPrefix + id if err := rs.db.Cmd("DEL", key).Err; err != nil { return err } - cache2go.RemKey(key) + cache2go.RemKey(key, cacheCommit(transactionID), transactionID) return nil } diff --git a/engine/storage_redis_local_test.go b/engine/storage_redis_local_test.go index e87ad31c9..a53e215b7 100644 --- a/engine/storage_redis_local_test.go +++ b/engine/storage_redis_local_test.go @@ -62,17 +62,17 @@ func TestSetGetDerivedCharges(t *testing.T) { &utils.DerivedCharger{RunID: "extra2", RequestTypeField: "*default", DirectionField: "*default", TenantField: "*default", CategoryField: "*default", AccountField: "ivo", SubjectField: "ivo", DestinationField: "*default", SetupTimeField: "*default", AnswerTimeField: "*default", UsageField: "*default"}, }} - if err := rds.SetDerivedChargers(keyCharger1, charger1); err != nil { + if err := rds.SetDerivedChargers(keyCharger1, charger1, utils.NonTransactional); err != nil { t.Error("Error on setting DerivedChargers", err.Error()) } // Retrieve from db - if rcvCharger, err := rds.GetDerivedChargers(keyCharger1, true); err != nil { + if rcvCharger, err := rds.GetDerivedChargers(keyCharger1, true, utils.NonTransactional); err != nil { t.Error("Error when retrieving DerivedCHarger", err.Error()) } else if !reflect.DeepEqual(rcvCharger, charger1) { t.Errorf("Expecting %v, received: %v", charger1, rcvCharger) } // Retrieve from cache - if rcvCharger, err := rds.GetDerivedChargers(keyCharger1, false); err != nil { + if rcvCharger, err := rds.GetDerivedChargers(keyCharger1, false, utils.NonTransactional); err != nil { t.Error("Error when retrieving DerivedCHarger", err.Error()) } else if !reflect.DeepEqual(rcvCharger, charger1) { t.Errorf("Expecting %v, received: %v", charger1, rcvCharger) diff --git a/engine/storage_test.go b/engine/storage_test.go index 38c603c6e..ab5a26163 100644 --- a/engine/storage_test.go +++ b/engine/storage_test.go @@ -75,7 +75,7 @@ func TestMsgpackTime(t *testing.T) { } func TestStorageDestinationContainsPrefixShort(t *testing.T) { - dest, err := ratingStorage.GetDestination("NAT", true) + dest, err := ratingStorage.GetDestination("NAT", true, utils.NonTransactional) precision := dest.containsPrefix("0723") if err != nil || precision != 4 { t.Error("Error finding prefix: ", err, precision) @@ -83,7 +83,7 @@ func TestStorageDestinationContainsPrefixShort(t *testing.T) { } func TestStorageDestinationContainsPrefixLong(t *testing.T) { - dest, err := ratingStorage.GetDestination("NAT", true) + dest, err := ratingStorage.GetDestination("NAT", true, utils.NonTransactional) precision := dest.containsPrefix("0723045326") if err != nil || precision != 4 { t.Error("Error finding prefix: ", err, precision) @@ -91,7 +91,7 @@ func TestStorageDestinationContainsPrefixLong(t *testing.T) { } func TestStorageDestinationContainsPrefixNotExisting(t *testing.T) { - dest, err := ratingStorage.GetDestination("NAT", true) + dest, err := ratingStorage.GetDestination("NAT", true, utils.NonTransactional) precision := dest.containsPrefix("072") if err != nil || precision != 0 { t.Error("Error finding prefix: ", err, precision) @@ -99,15 +99,15 @@ func TestStorageDestinationContainsPrefixNotExisting(t *testing.T) { } func TestStorageCacheRefresh(t *testing.T) { - ratingStorage.SetDestination(&Destination{"T11", []string{"0"}}) - ratingStorage.GetDestination("T11", false) - ratingStorage.SetDestination(&Destination{"T11", []string{"1"}}) + ratingStorage.SetDestination(&Destination{"T11", []string{"0"}}, utils.NonTransactional) + ratingStorage.GetDestination("T11", false, utils.NonTransactional) + ratingStorage.SetDestination(&Destination{"T11", []string{"1"}}, utils.NonTransactional) t.Log("Test cache refresh") err := ratingStorage.PreloadRatingCache() if err != nil { t.Error("Error cache rating: ", err) } - d, err := ratingStorage.GetDestination("T11", false) + d, err := ratingStorage.GetDestination("T11", false, utils.NonTransactional) p := d.containsPrefix("1") if err != nil || p == 0 { t.Error("Error refreshing cache:", d) @@ -145,23 +145,23 @@ func TestStorageGetAliases(t *testing.T) { }, }, } - accountingStorage.SetAlias(ala) - accountingStorage.SetReverseAlias(ala) - accountingStorage.SetAlias(alb) - accountingStorage.SetReverseAlias(alb) - foundAlias, err := accountingStorage.GetAlias(ala.GetId(), true) + accountingStorage.SetAlias(ala, utils.NonTransactional) + accountingStorage.SetReverseAlias(ala, utils.NonTransactional) + accountingStorage.SetAlias(alb, utils.NonTransactional) + accountingStorage.SetReverseAlias(alb, utils.NonTransactional) + foundAlias, err := accountingStorage.GetAlias(ala.GetId(), true, utils.NonTransactional) if err != nil || len(foundAlias.Values) != 1 { t.Errorf("Alias get error %+v, %v: ", foundAlias, err) } - foundAlias, err = accountingStorage.GetAlias(alb.GetId(), true) + foundAlias, err = accountingStorage.GetAlias(alb.GetId(), true, utils.NonTransactional) if err != nil || len(foundAlias.Values) != 1 { t.Errorf("Alias get error %+v, %v: ", foundAlias, err) } - foundAlias, err = accountingStorage.GetAlias(ala.GetId(), false) + foundAlias, err = accountingStorage.GetAlias(ala.GetId(), false, utils.NonTransactional) if err != nil || len(foundAlias.Values) != 1 { t.Errorf("Alias get error %+v, %v: ", foundAlias, err) } - foundAlias, err = accountingStorage.GetAlias(alb.GetId(), false) + foundAlias, err = accountingStorage.GetAlias(alb.GetId(), false, utils.NonTransactional) if err != nil || len(foundAlias.Values) != 1 { t.Errorf("Alias get error %+v, %v: ", foundAlias, err) } @@ -184,7 +184,7 @@ func TestStorageCacheGetReverseAliases(t *testing.T) { Subject: "b1", Context: "*other", } - accountingStorage.GetReverseAlias("aaa"+"Subject"+utils.ALIAS_CONTEXT_RATING, false) + accountingStorage.GetReverseAlias("aaa"+"Subject"+utils.ALIAS_CONTEXT_RATING, false, utils.NonTransactional) if x, ok := cache2go.Get(utils.REVERSE_ALIASES_PREFIX + "aaa" + "Subject" + utils.ALIAS_CONTEXT_RATING); ok { aliasKeys := x.([]string) if len(aliasKeys) != 1 { @@ -193,7 +193,7 @@ func TestStorageCacheGetReverseAliases(t *testing.T) { } else { t.Error("Error getting reverse alias: ", err) } - accountingStorage.GetReverseAlias("aaa"+"Account"+"*other", false) + accountingStorage.GetReverseAlias("aaa"+"Account"+"*other", false, utils.NonTransactional) if x, ok := cache2go.Get(utils.REVERSE_ALIASES_PREFIX + "aaa" + "Account" + "*other"); ok { aliasKeys := x.([]string) if len(aliasKeys) != 1 { @@ -221,8 +221,8 @@ func TestStorageCacheRemoveCachedAliases(t *testing.T) { Subject: "b1", Context: "*other", } - accountingStorage.RemoveAlias(ala.GetId()) - accountingStorage.RemoveAlias(alb.GetId()) + accountingStorage.RemoveAlias(ala.GetId(), utils.NonTransactional) + accountingStorage.RemoveAlias(alb.GetId(), utils.NonTransactional) if _, ok := cache2go.Get(utils.ALIASES_PREFIX + ala.GetId()); ok { t.Error("Error removing cached alias: ", ok) diff --git a/engine/tp_reader.go b/engine/tp_reader.go index 023160bcd..5b11d2232 100644 --- a/engine/tp_reader.go +++ b/engine/tp_reader.go @@ -96,8 +96,8 @@ func (tpr *TpReader) LoadDestinationsFiltered(tag string) (bool, error) { for _, tpDest := range tpDests { dest.AddPrefix(tpDest.Prefix) } - tpr.ratingStorage.SetDestination(dest) - tpr.ratingStorage.SetReverseDestination(dest) + tpr.ratingStorage.SetDestination(dest, utils.NonTransactional) + tpr.ratingStorage.SetReverseDestination(dest, utils.NonTransactional) return len(tpDests) > 0, err } @@ -249,12 +249,12 @@ func (tpr *TpReader) LoadRatingPlansFiltered(tag string) (bool, error) { return false, fmt.Errorf("could not get destination for tag %v", drate.DestinationId) } for _, destination := range dms { - tpr.ratingStorage.SetDestination(destination) - tpr.ratingStorage.SetReverseDestination(destination) + tpr.ratingStorage.SetDestination(destination, utils.NonTransactional) + tpr.ratingStorage.SetReverseDestination(destination, utils.NonTransactional) } } } - if err := tpr.ratingStorage.SetRatingPlan(ratingPlan); err != nil { + if err := tpr.ratingStorage.SetRatingPlan(ratingPlan, utils.NonTransactional); err != nil { return false, err } } @@ -331,7 +331,7 @@ func (tpr *TpReader) LoadRatingProfilesFiltered(qriedRpf *TpRatingProfile) error CdrStatQueueIds: strings.Split(tpRa.CdrStatQueueIds, utils.INFIELD_SEP), }) } - if err := tpr.ratingStorage.SetRatingProfile(resultRatingProfile); err != nil { + if err := tpr.ratingStorage.SetRatingProfile(resultRatingProfile, utils.NonTransactional); err != nil { return err } } @@ -404,7 +404,7 @@ func (tpr *TpReader) LoadSharedGroupsFiltered(tag string, save bool) (err error) } if save { for _, sg := range tpr.sharedGroups { - if err := tpr.ratingStorage.SetSharedGroup(sg); err != nil { + if err := tpr.ratingStorage.SetSharedGroup(sg, utils.NonTransactional); err != nil { return err } } @@ -777,7 +777,7 @@ func (tpr *TpReader) LoadAccountActionsFiltered(qriedAA *TpAccountAction) error if accountAction.ActionPlanId != "" { // get old userBalanceIds exitingAccountIds := make(utils.StringMap) - existingActionPlan, err := tpr.ratingStorage.GetActionPlan(accountAction.ActionPlanId, true) + existingActionPlan, err := tpr.ratingStorage.GetActionPlan(accountAction.ActionPlanId, true, utils.NonTransactional) if err == nil && existingActionPlan != nil { exitingAccountIds = existingActionPlan.AccountIDs } @@ -858,7 +858,7 @@ func (tpr *TpReader) LoadAccountActionsFiltered(qriedAA *TpAccountAction) error } } // write action plan - err = tpr.ratingStorage.SetActionPlan(accountAction.ActionPlanId, actionPlan, false) + err = tpr.ratingStorage.SetActionPlan(accountAction.ActionPlanId, actionPlan, false, utils.NonTransactional) if err != nil { return errors.New(err.Error() + " (SetActionPlan): " + accountAction.ActionPlanId) } @@ -963,7 +963,7 @@ func (tpr *TpReader) LoadAccountActionsFiltered(qriedAA *TpAccountAction) error actionIDs = append(actionIDs, atr.ActionsID) } // write action triggers - err = tpr.ratingStorage.SetActionTriggers(accountAction.ActionTriggersId, actionTriggers) + err = tpr.ratingStorage.SetActionTriggers(accountAction.ActionTriggersId, actionTriggers, utils.NonTransactional) if err != nil { return errors.New(err.Error() + " (SetActionTriggers): " + accountAction.ActionTriggersId) } @@ -1078,7 +1078,7 @@ func (tpr *TpReader) LoadAccountActionsFiltered(qriedAA *TpAccountAction) error } // write actions for k, as := range facts { - err = tpr.ratingStorage.SetActions(k, as) + err = tpr.ratingStorage.SetActions(k, as, utils.NonTransactional) if err != nil { return err } @@ -1173,7 +1173,7 @@ func (tpr *TpReader) LoadDerivedChargersFiltered(filter *TpDerivedCharger, save } if save { for dcsKey, dcs := range tpr.derivedChargers { - if err := tpr.ratingStorage.SetDerivedChargers(dcsKey, dcs); err != nil { + if err := tpr.ratingStorage.SetDerivedChargers(dcsKey, dcs, utils.NonTransactional); err != nil { return err } } @@ -1308,7 +1308,7 @@ func (tpr *TpReader) LoadCdrStatsFiltered(tag string, save bool) (err error) { return fmt.Errorf("could not get action triggers for cdr stats id %s: %s", cs.Id, triggerTag) } // write action triggers - err = tpr.ratingStorage.SetActionTriggers(triggerTag, triggers) + err = tpr.ratingStorage.SetActionTriggers(triggerTag, triggers, utils.NonTransactional) if err != nil { return errors.New(err.Error() + " (SetActionTriggers): " + triggerTag) } @@ -1412,7 +1412,7 @@ func (tpr *TpReader) LoadCdrStatsFiltered(tag string, save bool) (err error) { if save { // write actions for k, as := range tpr.actions { - err = tpr.ratingStorage.SetActions(k, as) + err = tpr.ratingStorage.SetActions(k, as, utils.NonTransactional) if err != nil { return err } @@ -1499,8 +1499,8 @@ func (tpr *TpReader) LoadAliasesFiltered(filter *TpAlias) (bool, error) { av.Pairs[tpAlias.Target][tpAlias.Original] = tpAlias.Alias } - tpr.accountingStorage.SetAlias(alias) - tpr.accountingStorage.SetReverseAlias(alias) + tpr.accountingStorage.SetAlias(alias, utils.NonTransactional) + tpr.accountingStorage.SetReverseAlias(alias, utils.NonTransactional) return len(tpAliases) > 0, err } @@ -1645,7 +1645,7 @@ func (tpr *TpReader) WriteToDatabase(flush, verbose, disable_reverse bool) (err log.Print("Destinations:") } for _, d := range tpr.destinations { - err = tpr.ratingStorage.SetDestination(d) + err = tpr.ratingStorage.SetDestination(d, utils.NonTransactional) if err != nil { return err } @@ -1662,7 +1662,7 @@ func (tpr *TpReader) WriteToDatabase(flush, verbose, disable_reverse bool) (err log.Print("Rating Plans:") } for _, rp := range tpr.ratingPlans { - err = tpr.ratingStorage.SetRatingPlan(rp) + err = tpr.ratingStorage.SetRatingPlan(rp, utils.NonTransactional) if err != nil { return err } @@ -1674,7 +1674,7 @@ func (tpr *TpReader) WriteToDatabase(flush, verbose, disable_reverse bool) (err log.Print("Rating Profiles:") } for _, rp := range tpr.ratingProfiles { - err = tpr.ratingStorage.SetRatingProfile(rp) + err = tpr.ratingStorage.SetRatingProfile(rp, utils.NonTransactional) if err != nil { return err } @@ -1715,7 +1715,7 @@ func (tpr *TpReader) WriteToDatabase(flush, verbose, disable_reverse bool) (err } } } - err = tpr.ratingStorage.SetActionPlan(k, ap, false) + err = tpr.ratingStorage.SetActionPlan(k, ap, false, utils.NonTransactional) if err != nil { return err } @@ -1727,7 +1727,7 @@ func (tpr *TpReader) WriteToDatabase(flush, verbose, disable_reverse bool) (err log.Print("Action Triggers:") } for k, atrs := range tpr.actionsTriggers { - err = tpr.ratingStorage.SetActionTriggers(k, atrs) + err = tpr.ratingStorage.SetActionTriggers(k, atrs, utils.NonTransactional) if err != nil { return err } @@ -1739,7 +1739,7 @@ func (tpr *TpReader) WriteToDatabase(flush, verbose, disable_reverse bool) (err log.Print("Shared Groups:") } for k, sg := range tpr.sharedGroups { - err = tpr.ratingStorage.SetSharedGroup(sg) + err = tpr.ratingStorage.SetSharedGroup(sg, utils.NonTransactional) if err != nil { return err } @@ -1751,7 +1751,7 @@ func (tpr *TpReader) WriteToDatabase(flush, verbose, disable_reverse bool) (err log.Print("LCR Rules:") } for k, lcr := range tpr.lcrs { - err = tpr.ratingStorage.SetLCR(lcr) + err = tpr.ratingStorage.SetLCR(lcr, utils.NonTransactional) if err != nil { return err } @@ -1763,7 +1763,7 @@ func (tpr *TpReader) WriteToDatabase(flush, verbose, disable_reverse bool) (err log.Print("Actions:") } for k, as := range tpr.actions { - err = tpr.ratingStorage.SetActions(k, as) + err = tpr.ratingStorage.SetActions(k, as, utils.NonTransactional) if err != nil { return err } @@ -1787,7 +1787,7 @@ func (tpr *TpReader) WriteToDatabase(flush, verbose, disable_reverse bool) (err log.Print("Derived Chargers:") } for key, dcs := range tpr.derivedChargers { - err = tpr.ratingStorage.SetDerivedChargers(key, dcs) + err = tpr.ratingStorage.SetDerivedChargers(key, dcs, utils.NonTransactional) if err != nil { return err } @@ -1823,7 +1823,7 @@ func (tpr *TpReader) WriteToDatabase(flush, verbose, disable_reverse bool) (err log.Print("Aliases:") } for _, al := range tpr.aliases { - err = tpr.accountingStorage.SetAlias(al) + err = tpr.accountingStorage.SetAlias(al, utils.NonTransactional) if err != nil { return err } @@ -1844,7 +1844,7 @@ func (tpr *TpReader) WriteToDatabase(flush, verbose, disable_reverse bool) (err if err != nil { return err } - if err = tpr.accountingStorage.SetResourceLimit(rl); err != nil { + if err = tpr.accountingStorage.SetResourceLimit(rl, utils.NonTransactional); err != nil { return err } if verbose { diff --git a/engine/version.go b/engine/version.go index 6d851f86a..b66d90fe4 100644 --- a/engine/version.go +++ b/engine/version.go @@ -14,7 +14,7 @@ func CheckVersion(acntDB AccountingStorage) error { } dbVersion, err := acntDB.GetStructVersion() if err != nil { - if lhList, err := acntDB.GetLoadHistory(1, true); err != nil || len(lhList) == 0 { + if lhList, err := acntDB.GetLoadHistory(1, true, utils.NonTransactional); err != nil || len(lhList) == 0 { // no data, write version if err := acntDB.SetStructVersion(CurrentVersion); err != nil { utils.Logger.Warning(fmt.Sprintf("Could not write current version to db: %v", err)) diff --git a/utils/consts.go b/utils/consts.go index dfd719b57..dd9995d36 100644 --- a/utils/consts.go +++ b/utils/consts.go @@ -308,4 +308,5 @@ const ( MetaUnixTimestamp = "*unix_timestamp" MetaPostCDR = "*post_cdr" MetaDumpToFile = "*dump_to_file" + NonTransactional = "" // used in transactional cache mechanism )